zoukankan      html  css  js  c++  java
  • 多进程,进程池,协程

    多进程

    并行,同时执行。 一个程序运行起来之后,代码用到的资源称之为进程,它是操作系统分配资源的基本单位,不仅可以通过线程完成多任务,进程也是可以的

    进程之间是相互独立的

    cpu计算密集的时候适合用多进程

    有几核CPU就可以同时执行几个进程

    开启进程需要调用 multiprocessing 模块

    import multiprocessing      #调用进程模块
    import time
    def test1():
        for i in range(5):
            time.sleep(1)
            print('test', i)
    def test2():
        for i in range(5):
            time.sleep(1)
            print('test', i)
    
    if __name__ == '__main__':      #固定格式(必须加)后面的执行代码要缩进
        p1 = multiprocessing.Process(target=test1)  #添加一个test1变成一个子进程赋值给p1
        p2 = multiprocessing.Process(target=test2)
        p1.start()      #开启p1子进程
        p2.start()
    

     结果:

    #停顿一秒
    test 0
    test 0
    #停顿一秒
    test 1
    test 1
    #停顿一秒
    test 2
    test 2
    #停顿一秒
    test 3
    test 3
    #停顿一秒
    test 4
    test 4
    

     进程之间不共享,相互独立

    import multiprocessing
    g_num = 0
    def edit():
        global g_num
        for i in range(10):
            g_num += 1
        print(g_num)
    def reader():
        print(' ')
        print(g_num)
    
    if __name__ == '__main__':
        p1 = multiprocessing.Process(target=edit)
        p2 = multiprocessing.Process(target=reader())
        p1.start()
        p2.start()
        print(g_num)
    
    结果:

    全局变量没有被改变

    0 
    0
    10
    进程池的并发

    apply_async 是异步非阻塞的。即不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。首先主进程开始运行,碰到子进程后,主进程仍可以先运行,等到操作系统进行进程切换的时候,在交给子进程运行。可以做到不等待子进程执行完毕,主进程就已经执行完毕,并退出程序。

    import multiprocessing      #调用进程模块
    from multiprocessing import Pool    #调用进程池模块
    import time
    import threading
    g_num = 0
    def test1():
        for i in range(10):
            time.sleep(1)
            print('test1', i)
    
    def test2():
        for i in range(10):
            time.sleep(1)
            print('test2', i)
    
    def test3():
        for i in range(10):
            time.sleep(1)
            print('test3', i)
    
    
    if __name__ == '__main__':
        pool = Pool() #括号里写几就代表可以允许同时执行几个进程,不写的话就按照cpu的各项指标系统分配同时执行的进程数。
        pool.apply_async(test1) ##维持执行的进程,当一个进程执行完毕后会添加新的进程进去
        pool.apply_async(test2)
        pool.apply_async(test3)
        pool.close()    #关闭进程池,表示不能再往进程池中添加进程,需要在join之前调用
        pool.join()     #等待进程池中的所有进程执行完毕

    进程包括线程(线程是轻量级的)

    线程包括协程(协程是微量级的)

    协程比线程更加适合IO密集的操作

    协程

    协程,又称微线程,纤程。英文名Coroutine。 首先我们得知道协程是啥?协程其实可以认为是比线程更小的执行单元。 为啥说他是一个执行单元,因为他自带CPU上下文。这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程。 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。

    那么这个过程看起来和线程差不多。其实不然, 线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。 操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。

    需要调用 gevent 模块,第三方模块,需要pip下载。

    import gevent,time
    from gevent import monkey
    monkey.patch_all()
    def test1():
        for i in range(10):
            time.sleep(1)
            print('1===>', i)
    
    def test2():
        for i in range(10):
            time.sleep(2)
            print('2===>', i)
    
    g1 = gevent.spawn(test1)
    g2 = gevent.spawn(test2)
    g1.join()
    g2.join()

    因为第一个协程挺一秒,第二个协程停2秒,所以CPU一个时间段内执行两次协程1,一次协程2

    1===> 0
    2===> 0
    1===> 1
    1===> 2
    2===> 1
    1===> 3
    1===> 4
    2===> 2
    2===> 3
    2===> 4
  • 相关阅读:
    赠与今年的大学毕业生(胡适先生30年代的文章,仍不过时)
    统一管理磁盘上的开源代码
    生成sqlite导入库的做法
    提高二维矢量绘图效率之一般做法
    boost库命名规则的优点
    如何把腾讯微博挂到CSDN博客上
    fatal error C1902 Program database manager mismatch; please check your installation问题的解决
    智能指针变量做函数参数的一个值得注意的地方
    PC会消亡吗?
    软件制造问题的微软答案
  • 原文地址:https://www.cnblogs.com/dayle/p/10028617.html
Copyright © 2011-2022 走看看