zoukankan      html  css  js  c++  java
  • 线程

    线程被称作轻量级的进程。  GIL:全局解释锁(只有Cpython解释器才有)
                                             线程会被强迫放弃CPU的因素
                                                (线程会受时间片影响)(GIL会限制每个线程的执行时间,一般是5毫秒)(或者限制线程执行固定数量的字节码)
                                        对于线程来说,因为有了GIL,所以没有真正的并行
    
              计算机的执行单位以线程为单位。计算机的最小可执行是线程。
              进程是资源分配的基本单位。线程是可执行的基本单位,是可被调度的基本单位。
              线程不可以自己独立拥有资源。线程的执行,必须依赖于所属进程中的资源。
              进程中必须至少应该有一个线程。
    
              线程又分为用户级线程和内核级线程(了解)
                用户级线程:对于程序员来说的,这样的线程完全被程序员控制执行,调度
                内核级线程:对于计算机内核来说的,这样的线程完全被内核控制调度。
    
          进程由 代码段  数据段  PCB组成(process control block)
          线程由 代码段  数据段  TCB组成(thread control block)
          
    #模块:threading
    #导入方法:from threading import Thread
    
    #线程和进程的比较
              thread - 线程
              import thread 操作线程的模块
              import threading 用这个去操作线程
             (1) cpu切换进程要比cpu切换线程 慢很多
                 在python中,如果IO操作过多的话,使用多线程最好了
             (2) 在同一个进程内,所有线程共享这个进程的pid,也就是说所有线程共享所属进程的所有资源和内存地址
             (3) 在同一个进程内,所有线程共享该进程中的全局变量
    
             (4) 因为有GIL锁的存在,在Cpython中,没有真正的线程并行。但是有真正的多进程并行
                 当你的任务是计算密集的情况下,使用多进程好
                总结:在CPython中,IO密集用多线程,计算密集用多进程
    
            (5)关于守护线程和守护进程的事情(注意:代码执行结束并不代表程序结束)
                守护进程:要么自己正常结束,要么根据父进程的代码执行结束而结束
                守护线程:要么自己正常结束,要么根据父线程的执行结束而结束       
           
    #线程方法:
            (1)锁机制
                 递归锁
                     RLock()    可以有无止尽的锁,但是会有一把万能钥匙
                 互斥锁:
                     Lock()     一把钥匙配一把锁
                 GIL:全局解释器锁
                    锁的是线程,是CPython解释器上的一个锁,锁的是线程,意思是在同一时间只允许一个线程访问cpu
            (2) 信号量:
                from threading import Semaphore
                去看多进程的信号量
    
            (3) 事件
                from threading import Event
                去看多进程的事件机制
    
            (4) 条件
                from threading import Condition
                条件是让程序员自行去调度线程的一个机制
                # Condition涉及4个方法
                # acquire()
                # release()
                # wait()    是指让线程阻塞住
                # notify(int)  是指给wait发一个信号,让wait变成不阻塞
                #     int是指,你要给多少给wait发信号
    5) 定时器
                from threading import Timer
                    # Timer(time,func)
                    # time:睡眠的时间,以秒为单位
                    # func:睡眠时间之后,需要执行的任务
    
    #基本使用方法:
    import threading
    from threading import Thread
    import time
    ################################# 常规方法
    # def func():
    #     print('这是一个子线程')
    #     time.sleep(2)
    #
    # if __name__ == '__main__':
    #     t = Thread(target=func,args=())
    #     t.start()
    
    
    #################################类的方法
    
    
    # class MyThread(Thread):
    #     def __init__(self):
    #         super(MyThread, self).__init__()
    #     def run(self):
    #         print('我是一个子线程')
    #
    # t = MyThread()
    # t.start()
    模块:Condition
    导入方法:from threading import Condition,Thread
    模块方法:con=Condition()
        #con.acquire()
        #con.release()
        #con.wait()  # 假设有一个初始状态为False,阻塞。一旦接受到notify的信号后,变为True,不再阻塞
        #con.notify(int)  给wait发信号,发int个信号,会传递给int个wait,让int个线程正常执行
        
    注意事项:
        同一个线程内,递归锁可以多次acquire,但互斥锁不可以
        不同线程,递归锁是保证只能一个线程用,并多次acquire,其他线程等待
    
    #例子
    from threading import Condition,Thread
    import time
    
    def func(con,i):
        con.acquire()# 主线程和10个子线程都在抢夺递归锁的一把钥匙。
        # 如果主线程抢到钥匙,主线程执行while 1,input,然后notify发信号,还钥匙。但是,此时如果主线程执行特别快
        # 极有可能接下来主线程又会拿到钥匙,那么此时哪怕其他10个子线程的wait接收到信号,但是因为没有拿到钥匙,所以其他子线程还是不会执行
        con.wait()
        print('第%s个线程执行了'%i)
        con.release()
    
    con = Condition()
    for i in range(10):
        t = Thread(target=func,args = (con,i))
        t.start()
    while 1:
        # print(123)
        con.acquire()
        num = input('>>>')
        con.notify(int(num))
        con.release()
        time.sleep(0.5)
  • 相关阅读:
    flutter开发dart基本数据类型与java、kotlin、oc、swift对照表
    flutter输入框TextField设置高度以及背景色等样式的正确姿势
    flutter开发tab页面嵌套滚动的最简洁实现方式
    flutter开发自定义ExpandListView分组列表组件
    RedisUtil-redisTemplate-setNX
    数据库无限层级分类设计
    魔方
    CountDownLatch在SpringBoot中配合@Async使用
    会话刷新Token校验流程
    Mybatis 夺命十八问,顶不住了!
  • 原文地址:https://www.cnblogs.com/god-for-speed/p/11719102.html
Copyright © 2011-2022 走看看