最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Python的学习笔记:线程,进程,协程

    正文概述    2020-04-15   218

    Python的学习笔记:线程,进程,协程

    一、线程(Thread)

      1、定义:线程是操作系统能进行运算调度的最小单位,它包含在进程中,是进程的实际运作单位,一条线程是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。简单理解:线程是一系列指令的集合,操作系统通过这些指令调用硬件。

      2、同一个线程中的所有线程共享同一个内存空间资源,

     

    二、进程(Progress)

      1、定义:一个程序对各资源管理和调用的集合就是进程,比如QQ对网卡、内存、硬盘的调度和管理。对于操作系统来说,某一个进程是统一的整体。进程操作CPU就要先创建一个线程。进程本身是一个资源集合,执行需要靠线程。

     

    三、线程和进程的区别

      1、同个进程的线程之间共享内存空间,包括数据交换和通信,但不同进程之间的内存是独立的

      2、子进程是克隆了一份父进程的数据,子进程之间是互相独立的,不能互相访问,数据也不能共享。

      3、两个进程要通信,必须通过一个中间进程代理来实现。

      4、一个线程可以操作同一个进程中的其他线程,但是进程只能操作子进程

      5、对主线程的修改,可能会影响到其他的子线程,因为他们共享内存数据,但对主进程的修改,不会影响其他子进程。

     

    四、多线程的代码:

    import threading
    import time
    
    
    class MyThread(threading.Thread):
        """
        # 用自定义一个子类的方式来启动线程
        """
    
        def __init__(self, n):
            super(MyThread, self).__init__()
            self.n = n
    
        def run(self):
            print("你好,%s" % self.n)
            time.sleep(2)
    
    
    start_time = time.time()
    thread_list = []
    
    # 启动50个线程
    for i in range(50):
        t1 = MyThread("t%s" % i)
        t1.start()
        thread_list.append(t1)
    # 等待所有线程执行完毕后主线程再继续执行
    for i in thread_list:
        i.join()
    
    print("总共执行时间:%s" % float(time.time() - start_time))

    五、全局解释器锁(GIL)

      1、定义:GIL 是最流行的 CPython 解释器(平常称为 Python)中的一个技术术语,中文译为全局解释器锁,其本质上类似操作系统的 Mutex(即互斥锁,意思是我修改的时候你不能修改,也就是锁的意思)

      2、功能:在 CPython 解释器中执行的每一个 Python 线程,都会先锁住自己,以阻止别的线程执行,这样在同个时间一个CPU只执行一个线程。当然,CPython 不可能容忍一个线程一直独占解释器,check interval 机制会在一个时间段后释放前面一个线程的全局锁执行下一个线程,以达到轮流执行线程的目的。这样一来,用户看到的就是“伪”并行,即 Python 线程在交替执行,来模拟真正并行的线程。

      3、CPython 引进 GIL,可以最大程度上规避类似内存管理这样复杂的竞争风险问题,有了 GIL,并不意味着无需去考虑线程安全,因为即便 GIL 仅允许一个 Python 线程执行,但别忘了 Python 还有 check interval 这样的抢占机制。所以就要引入线程锁的机制,保证同个时间只有一个线程修改数据。

    Python的学习笔记:线程,进程,协程

      4、线程锁的代码如下

    import threading
    import time
    
    num = 0
    
    lock_obj = threading.Lock()
    
    
    def run():
        # 申请锁,使别的线程进不来
        lock_obj.acquire()
        global num
        time.sleep(1.1)
        num = num + 1
        # 解锁,解锁后别的线程可以进来
        lock_obj.release()
    
    
    t_list = []
    start_time = time.time()
    # 启动1000个线程
    for i in range(100):
        t1 = threading.Thread(target=run)
        t1.start()
        t_list.append(t1)
    
    for i in t_list:
        i.join()
    
    time.sleep(3)
    print("num:%d" % num)
    print("time:%f" % float(time.time() - start_time))

    六、递归锁:

      1、定义:一个锁套另外一个锁,形成锁止循环,这种情况就要用到递归锁RLOCK

    import threading, time
    def run1():
        print("grab the first part data")
        lock.acquire()
        global num
        num += 1
        lock.release()
        return num
    def run2():
        print("grab the second part data")
        lock.acquire()
        global num2
        num2 += 1
        lock.release()
        return num2
    def run3():
        lock.acquire()
        res = run1()
        print('--------between run1 and run2-----')
        res2 = run2()
        lock.release()
        print(res, res2)
    num, num2 = 0, 0
    # 这里如果用Lock()就会无限循环,找不到具体用哪个钥匙打开锁,如果用RLock就不会,如果又多重锁嵌套的情况一定要用递归锁
    lock = threading.Lock()
    for i in range(1):
        t = threading.Thread(target=run3)
        t.start()
    while threading.active_count() != 1:
        print("当前活跃的线程数:",threading.active_count())
    else:
        print('----all threads done---')
        print("打印num和num2:",num, num2)

    七、信号量(Semaphore)  

      1、允许同时间最多几个线程进入执行,每出来一个进去一个,同时保持预先设置的线程最大允许数量。

    import threading, time
    
    
    def run(n):
        semaphore.acquire()
        time.sleep(1)
        print("run the thread: %s\n" % n)
        semaphore.release()
    
    if __name__ == '__main__':
        semaphore = threading.BoundedSemaphore(5)  # 最多允许5个线程同时运行
        for i in range(22):
            t = threading.Thread(target=run, args=(i,))
            t.start()
    while threading.active_count() != 1:
        pass  # print threading.active_count()
    else:
        print('----all threads done---')
        #print(num)

    八、事件(Event):

      1、定义:通过标识位和状态,来实现线程之间的交互。简单说,就是一个标志位,只有两种状态,一种是设置(Event.set()),一直是没有设置(Event.clear())。

      2、以下代码实现一个简单事件,一个线程控制红绿灯,另外一个线程控制车子,当红绿灯是红色的时候,车子停止,绿的时候,车子行驶的效果

    import time
    import threading
    
    
    event = threading.Event()
    
    def lighter():
        count = 0
        event.set()  # 刚开始的标识位先设置绿灯
        while True:
            if 5 < count < 10:  # 改成红灯
                event.clear()  # 把标志位清了
                print("\033[41;1mred light is on....\033[0m")
            elif count > 10:
                event.set()  # 变绿灯
                count = 0
            else:
                print("\033[42;1mgreen light is on....\033[0m")
            time.sleep(1)
            count += 1
    
    
    def car(name):
        while True:
            if event.is_set():  # 代表绿灯
                print("[%s] running..." % name)
                time.sleep(1)
            else:
                print("[%s] sees red light , waiting...." % name)
                event.wait()
                print("\033[34;1m[%s] green light is on, start going...\033[0m" % name)
    
    
    light = threading.Thread(target=lighter, )
    light.start()
    
    car1 = threading.Thread(target=car, args=("Tesla",))
    car1.start()

     3、Event类还有两个方法,wait()等待被设定,isset()判断是否被设定


    下载网 » Python的学习笔记:线程,进程,协程

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元