美文网首页
进程、线程、协程

进程、线程、协程

作者: 王大吉 | 来源:发表于2020-02-08 00:59 被阅读0次

    进程是资源分配的最小单位

    如果说进程和进程之间相当于程序与程序之间的关系,那么线程与线程之间就相当于程序内的任务和任务之间的关系。所以线程是依赖于进程的,也称为 「微进程」 。它是 程序执行过程中的最小单元 。

    进程是CPU资源分配的基本单位,线程是独立运行和独立调度的基本单位(CPU上真正运行的是线程)。进程拥有自己的资源空间,一个进程包含若干个线程,线程与CPU资源分配无关,多个线程共享同一进程内的资源。线程的调度与切换比进程快很多。

    CPU密集型代码(各种循环处理、计算等等):使用多进程。IO密集型代码(文件处理、网络爬虫等):使用多线程

    线程

    python3内置两个thread模块:

    _thread模块
    threading模块
    推荐使用threading模块
    1.数据共享,线程同步
    如果多个线程共同对某个数据修改,则可能产生混乱结果,为了保证数据的正确性,需要对多个线程进行同步。使用 Thread 对象的 Lock 或 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。

    示例代码:

    #!/usr/bin/env python3
    
    import time, threading
    
    var = 0
    lock = threading.Lock()
    
    def change_it(n):
        # 设为全局共享变量
        global var 
        var = var + n
        var = var - n
    
    def run_thread(n):
        for i in range(3):
            # 先要获取锁:
            lock.acquire()
            change_it(n)
            # 改完了一定要释放锁:
            lock.release()
    
    t1 = threading.Thread(target=run_thread, args=(5,))  # 逗号不能省!
    t2 = threading.Thread(target=run_thread, args=(8,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    

    2.线程阻塞
    threading.Event为事件处理的机制,全局定义了一个“Flag”:

    如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞;
    如果“Flag”值为True,那么执行event.wait 方法时便不再阻塞。
    clear:将“Flag”设置为False
    set:将“Flag”设置为True
    用 threading.Event 实现线程间通信,*可以使一个线程等待其他线程的通知,我们把这个Event传递到线程对象中,Event默认内置了一个标志,初始值为False。一旦该线程通过wait()方法进入等待状态,直到另一个线程调用该Event的set()方法将内置标志设置为True时,该Event会通知所有等待状态的线程恢复运行。
    示例代码:

    import threading, time
    import random
    
    def light():
        if not event.isSet():    #初始化evet的flag为真
            event.set()    #wait就不阻塞 #绿灯状态
        count = 0
        while True:
            if count < 10:
                print('\033[42;1m---green light on---\033[0m')
            elif count < 13:
                print('\033[43;1m---yellow light on---\033[0m')
            elif count < 20:
                if event.isSet():
                    event.clear()
                print('\033[41;1m---red light on---\033[0m')
            else:
                count = 0
                event.set()    #打开绿灯
            time.sleep(1)
            count += 1
    
    def car(n):
        while 1:
            time.sleep(random.randrange(3, 10))
            #print(event.isSet())
            if event.isSet():
                print("car [%s] is running..." % n)
            else:
                print('car [%s] is waiting for the red light...' % n)
                event.wait()    #红灯状态下调用wait方法阻塞,汽车等待状态
    
    if __name__ == '__main__':
        car_list = ['BMW', 'AUDI', 'SANTANA']
        event = threading.Event()
        Light = threading.Thread(target=light)
        Light.start()
        for i in car_list:
            t = threading.Thread(target=car, args=(i,))
            t.start()
    
    1. threading.active_count()
      返回当前存活的线程对象的数量;通过计算len(threading.enumerate())长度而来
    import threading, time
    
    def run():
        thread = threading.current_thread()
        print('%s is running...'% thread.getName())    #返回线程名称
        time.sleep(10)    #休眠10S方便统计存活线程数量
    
    if __name__ == '__main__':
        #print('The current number of threads is: %s' % threading.active_count())
        for i in range(10):
            print('The current number of threads is: %s' % threading.active_count())    #返回当前存活线程数量
            thread_alive = threading.Thread(target=run, name='Thread-***%s***' % i)
            thread_alive.start()
        thread_alive.join()
        print('\n%s thread is done...'% threading.current_thread().getName())
    
    1. threading.get_ident()
      返回线程pid
    import threading, time
    
    def run(n):
        print('-'*30)
        print("Pid is :%s" % threading.get_ident())  # 返回线程pid
    
    if __name__ == '__main__':
        threading.main_thread().setName('Chengd---python')    #自定义线程名
        for i in range(3):
            thread_alive = threading.Thread(target=run, args=(i,))
            thread_alive.start()
        thread_alive.join()
        print('\n%s thread is done...'% threading.current_thread().getName())    #获取线程名
    

    进程

    • os.fork()(非win)
    • multiprocessing(win)

    进程间通信

    • 写文件
    • redis
    • 共享内存

    协程

    def consumer():
        r = ''
        while True:
            n = yield r
            if not n:
                return
            print('[CONSUMER] Consuming %s...' % n)
            r = '200 OK'
    
    def produce(c):
        c.send(None)
        n = 0
        while n < 5:
            n = n + 1
            print('[PRODUCER] Producing %s...' % n)
            r = c.send(n)
            print('[PRODUCER] Consumer return: %s' % r)
        c.close()
    
    c = consumer()
    produce(c)
    

    相关文章

      网友评论

          本文标题:进程、线程、协程

          本文链接:https://www.haomeiwen.com/subject/vqkbxhtx.html