博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 之进程篇
阅读量:4615 次
发布时间:2019-06-09

本文共 3366 字,大约阅读时间需要 11 分钟。

多线程给我们的感觉

  1.因为GIL的存在,一个进程的多线程同一时刻只能进去一个,感觉是假的并发

  2.只适合I/O密集型的任务

  3.针对计算密集型,就挂了(变成串行了)

在python中想要充分利用多核cpu的优势,就可用多进程这个技术---multiprocessing

        multiprocessing是多进程的一个管理包。包含 Process、Queue、Pipe、Lock等组件。与thread类似

  该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。

但在使用这些共享API的时候,我们要注意以下几点:

  • 在UNIX平台上,当某个进程终结之后,该进程需要被其父进程调用wait,否则进程成为僵尸进程(Zombie)。所以,有必要对每个Process对象调用join()方法 (实际上等同于wait)。对于多线程来说,由于只有一个进程,所以不存在此必要性。
  • multiprocessing提供了threading包中没有的IPC(比如Pipe和Queue),效率上更高。应优先考虑Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式 (因为它们占据的不是用户进程的资源)。
  • 多进程应该避免共享资源。在多线程中,我们可以比较容易地共享资源,比如使用全局变量或者传递参数。在多进程情况下,由于每个进程有自己独立的内存空间,以上方法并不合适。此时我们可以通过共享内存和Manager的方法来共享资源。但这样做提高了程序的复杂度,并因为同步的需要而降低了程序的效率。

简单的例子:

from multiprocessing import Processimport osdef info(name):    print(name)    print(os.getppid())#在主进程运行的是的是这个是pychar的pid    print(os.getpid())if __name__ == "__main__":    info("main")    p=Process(target=info,args=("bob",))    p.start()    p.join()
View Code

进程之间通讯

1. Queue()  注意这个不同于进程queue。  每个进程之间使用pickle序列化实现

2. Pipe()

queue代码:注意q要当参数 传递给函数,不然无法使用。因为进程之间数据默认不共享的。

from multiprocessing import Process, Queuedef f(q,n):    q.put([42, n, 'hello'])if __name__ == '__main__':    q = Queue()    p_list=[]    for i in range(3):        p = Process(target=f, args=(q,i))        p_list.append(p)        p.start()    print(q.get())    print(q.get())    print(q.get())    for i in p_list:            i.join()
View Code

Pipe代码

from multiprocessing import Process, Pipe def f(conn):    conn.send([42, None, 'hello'])    conn.close() if __name__ == '__main__':    parent_conn, child_conn = Pipe()    p = Process(target=f, args=(child_conn,))    p.start()    print(parent_conn.recv())   # prints "[42, None, 'hello']"    p.join()
View Code

进程之间数据共享:Manager组件

from multiprocessing import Process, Managerdef f(d, l,n):    d[n] = '1'    d['2'] = 2    d[0.25] = None    l.append(n)    print(l)if __name__ == '__main__':    with Manager() as manager:        d = manager.dict()        l = manager.list(range(5))        p_list = []        for i in range(10):            p = Process(target=f, args=(d, l,i))            p.start()            p_list.append(p)        for res in p_list:            res.join()        print(d)        print(l)
View Code

    这里存在一个问题:数据共享 是不是要加锁

进程之间的数据同步LOCK:

用法与线程的一样:主要是为了防止进程抢占屏幕输出,避免输出错乱

from multiprocessing import Process, Lockdef f(l, i):    l.acquire()    try:        print('hello world', i)    finally:        l.release()if __name__ == '__main__':    lock = Lock()    for num in range(10):        Process(target=f, args=(lock, num)).start()
View Code

 

 进程池:                                                                                                                                                     

两种方法:
  • pool.apply
  • pool.apply_async
from multiprocessing import Poolimport os,timedef Foo(i):    time.sleep(2)    print("子进程",i,os.getpid())def Bar(arg):    print("Exec done",arg,os.getpid())if __name__=="__main__":    pool = Pool(3) #已经启动了10个进程,但是同一时刻只能有3个进程执行    for i in range(10):        #pool.apply(func=Foo,args=(i,)) #串行效果        #pool.apply_async(func=Foo,args=(i,))#异步方法,为了显示效果,必须加上,join。        pool.apply_async(func=Foo, args=(i,),callback=Bar) #异步使用回调函数,但是这个回调是在主进程中执行的,列如:在数据库连接的时候,如果在子进程连接,每个都要打开新的,不好    pool.close()    pool.join()#join之前,必须加上close,注意:close在前。
View Code

 

转载于:https://www.cnblogs.com/louhui/p/7967029.html

你可能感兴趣的文章
php面试题之三——PHP语言基础(基础部分)
查看>>
PHP基础-常用的数组相关处理函数
查看>>
在Python中使用glob模块查找文件路径的方法
查看>>
如何提高你的数据分析能力?
查看>>
。Java中的一些小细节
查看>>
前端服务化——页面搭建工具的死与生
查看>>
Dev chartControl添加提示层信息
查看>>
在CentOS上搭建最^1024基本的Nginx反向服务器
查看>>
eclipse中编码格式调整
查看>>
终端I/O之综述
查看>>
2.10 读取打快数据文件
查看>>
Markdown 语法
查看>>
Objective-c学习笔记03——内存管理
查看>>
zxin博客园开博第一天手记
查看>>
贝叶斯网络笔记
查看>>
每天进步一点点,,
查看>>
weblog expert分析工具使用
查看>>
Luogu 4159 [SCOI2009]迷路
查看>>
Flex性能优化常用手法总结
查看>>
javascript大神修炼记(7)——OOP思想(多态)
查看>>