python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。

Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。

1.Process

创建进程的类:Process([group [, target [, name [, args [, kwargs]]]]]),target表示调用对象,args表示调用对象的位置参数元组。kwargs表示调用对象的字典。name为别名。group实质上不使用。

方法:is_alive()、join([timeout])、run()、start()、terminate()。其中,Process以start()启动某个进程。

属性:authkey、daemon(要通过start()设置)、exitcode(进程在运行时为None、如果为–N,表示被信号N结束)、name、pid。其中daemon是父进程终止后自动终止,且自己不能产生新进程,必须在start()之前设置。

(1)创建多进程

1 #!/usr/bin/env python

2 #-*- coding: utf-8 -*-

3

4 from multiprocessing importProcess5 importtime6

7

8 deff(name):9 time.sleep(1)10 print("hello", name)11

12 if __name__ == '__main__':13 p1 = Process(target=f, args=['Bob1', ]) #target是创建的进程要执行的函数,args是传递给该函数的参数14 p2 = Process(target=f, args=['Bob2', ]) #这里进程p*的父进程是当前脚本,脚本的父进程是执行环境(eg:pycharm)15 p1.start()16 p2.start()17 p1.join()18 p2.join()19 time.sleep(1)20 print("----main process over----")

执行结果

hello Bob2

hello Bob1----main process over----

2、LOCK

当多个进程需要访问共享资源的时候,LOCK可以用来避免访问的冲突

1 #!/usr/bin/env python

2 #-*- coding: utf-8 -*-

3

4 '''

5 进程同步是说的进程一起执行6 '''

7 from multiprocessing importProcess,Lock8

9 deff(lock,i):10 lock.acquire()11 try:12 print('hello world',i)13 finally:14 lock.release()15

16 if __name__ == '__main__':17 lock =Lock()18

19 for num in range(10):20 Process(target=f,args=(lock,num)).start()

执行结果

hello world 0

hello world3hello world2hello world6hello world5hello world1hello world4hello world7hello world9hello world8

3、Queue、Pipe、Manager

分别利用Queue、Pipe、Manager实现进程间通信

(1)Queue

Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。

get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常。

(2) Pipe

Pipe方法返回(conn1, conn2)代表一个管道的两个端。Pipe方法有duplex参数,如果duplex参数为True(默认值),那么这个管道是全双工模式,也就是说conn1和conn2均可收发。duplex为False,conn1只负责接受消息,conn2只负责发送消息。

send和recv方法分别是发送和接受消息的方法。例如,在全双工模式下,可以调用conn1.send发送消息,conn1.recv接收消息。如果没有消息可接收,recv方法会一直阻塞。如果管道已经被关闭,那么recv方法会抛出EOFError。

(3) Manager

Manager()支持:list、dict、Namespace、Lock、Rlock、Semaphore、 BoundedSemaphore、Condition、Event、Barrier、Queue、Value、Array 其中常用的就list、dict。 注意:其中的list、dict都要通过Manager() 实现。

#!/usr/bin/env python#-*- coding: utf-8 -*-

'''进程之间是不能直接通信的,需要第三方作为通信媒介'''

'''以下是Queue实现数据传递代码'''

from multiprocessing importProcess,Queuedeff1(q):

q.put([22,'root','hello'])deff2(q):

q.put([23,'admin','hello'])'''以下是Pipe实现数据传递代码'''

from multiprocessing importProcess,Pipedeff3(conn):

conn.send([23,'admin1','hello'])deff4(conn):

conn.send([24, 'root', 'hello'])'''以下是Manager实现数据共享代码'''

from multiprocessing importProcess,Managerdeff(d,l,n):

d[n]=n

d['name'] = 'root'l.append(n)print(l)#以下是主程序

if __name__ == '__main__':print('''\033[42;1m 利用Queue实现进程间的通信 \033[0m''')'''这里的进程间通信是在同一父进程下不同子进程间的通信,因为队列q是在父进程实例化并

传递到每个子进程中。(当然可以在一个第三方文件里面创建一个队列,其余文件来调用是可以的)'''q= Queue() #生成一个第三方队列,用来存放子进程put的值

#这里的Queue是在queue.Queue的基础上,封装了能多进程访问

pq1 = Process(target=f1,args=(q,))

pq2= Process(target=f2,args=(q,)) #要把队列对象q当参数传递给各个子进程

pq1.start()

pq2.start()print('from parent 1:',q.get())print('from parent 2:',q.get())print('''\n\033[43;1m 利用Pipe实现进程间的通信 \033[0m''')

parent_conn,child_conn=Pipe()

pp1= Process(target=f3,args=(child_conn,))

pp2= Process(target=f4,args=(child_conn,))

pp1.start()

pp2.start()print('parent data from pp1:', parent_conn.recv())print('parent data from pp2:', parent_conn.recv())

parent_conn.close()#这个在子进程或父进程关闭都可以

print('''\n\033[43;1m 利用Manager实现进程间的数据共享 \033[0m''')'''这里Manager()支持:list、dict、Namespace、Lock、Rlock、Semaphore、

BoundedSemaphore、Condition、Event、Barrier、Queue、Value、Array

其中常用的就list、dict。

注意:其中的list、dict都要通过Manager() 实现'''

#manager = Manager() #注意这样后面需要关闭,用with...as...语句更方便

with Manager() as manager:

d=manager.dict()#l = manager.list() #这样生成空列表

l = manager.list(range(5))

process_list=[]for i in range(10):

p= Process(target=f,args=(d,l,i))

p.start()

process_list.append(p)for res inprocess_list:

res.join()print("执行结束l:",l)print("执行结束d:",d)

4、POOL

在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,此时可以发挥进程池的功效。

Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。

函数解释:

apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞的(理解区别,看例1例2结果区别)

close()    关闭pool,使其不在接受新的任务。

terminate()    结束工作进程,不在处理未完成的任务。

join()    主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。

1 #!/usr/bin/env python

2 #-*- coding: utf-8 -*-

3

4 '''

5 进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有6 可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。7

8 进程池方法:9 apply: 同步10 apply_async: 异步11 '''

12 from multiprocessing importProcess,Pool,freeze_support13 importtime14

15 defFoo(i):16 time.sleep(1)17 return i,i+100

18

19 defBar(arg):20 #print('arg:',arg)

21 data.append(arg)22 print('--> exec done [%s]: %s' % (arg[0],arg[1]))23

24 if __name__ == '__main__':25 freeze_support() #要导入,在win下必须有它,不然会报错。linux下不用

26

27 pool = Pool(3) #生成一个有5个进程序列的进程池实例

28 data =[]29 for i in range(10):30 #func为进程每次执行的函数,args是参数,callback是执行完func后执行的函数,

31 #并且callback会自动接收func的返回值作为函数参数。Foo是子进程执行的函数,callback是在

32 #父进程执行的函数,所以这里说明是子进程把执行结果返回给父进程里面的函数

33 pool.apply_async(func=Foo,args=(i,),callback=Bar)34 #pool.apply(func=Foo,args=(i,)) #进程同步,没啥用

35

36 print("end")37 pool.close()38 pool.join() #这里表示进程池中进程执行完毕后再关闭,若注释,那么程序直接关闭

39 #注意:这里是先close,再join

40 print('全局变量data:',data)

执行结果

end--> exec done [0]: 100

--> exec done [1]: 101

--> exec done [2]: 102

--> exec done [3]: 103

--> exec done [4]: 104

--> exec done [5]: 105

--> exec done [7]: 107

--> exec done [6]: 106

--> exec done [8]: 108

--> exec done [9]: 109全局变量data: [(0,100), (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (7, 107), (6, 106), (8, 108), (9, 109)]

5、Semaphore

Semaphore用来控制对共享资源的访问数量,例如池的最大连接数。

1 #!/usr/bin/env python

2 #-*- coding:utf8 -*-

3

4 importmultiprocessing5 importtime6

7

8 defrun(s, i):9 s.acquire()10 print(multiprocessing.current_process().name + "acquire");11 time.sleep(i)12 print(multiprocessing.current_process().name + "release\n");13 s.release()14

15

16 if __name__ == "__main__":17 s = multiprocessing.Semaphore(2) #最多允许3个进程同时运行

18

19 process_list =[]20 for i in range(3):21 p = multiprocessing.Process(target=run, args=(s, i * 2))22 p.start()23 process_list.append(p)24

25 for process inprocess_list:26 process.join()27

28 print('\033[31;1m 全部结束 \033[0m')

执行结果

Process-1acquire

Process-1release

Process-3acquire

Process-2acquire

Process-2release

Process-3release

全部结束

6、Event

用Event实现进程同步

1 #!/usr/bin/env python

2 #-*- coding:utf8 -*-

3

4 importmultiprocessing5 importtime6

7

8 defwait_for_event(e):9 print("wait_for_event: starting")10 e.wait()11 print("wairt_for_event: e.is_set()->" +str(e.is_set()))12

13

14 defwait_for_event_timeout(e, t):15 print("wait_for_event_timeout:starting")16 e.wait(t)17 print("wait_for_event_timeout:e.is_set->" +str(e.is_set()))18

19

20 if __name__ == "__main__":21 e =multiprocessing.Event()22 w1 = multiprocessing.Process(name="block",23 target=wait_for_event,24 args=(e,))25

26 w2 = multiprocessing.Process(name="non-block",27 target=wait_for_event_timeout,28 args=(e, 2))29 w1.start()30 w2.start()31

32 time.sleep(3)33

34 e.set()35 print("main: event is set")

执行结果

wait_for_event: starting

wait_for_event_timeout:starting

wait_for_event_timeout:e.is_set->False

wairt_for_event: e.is_set()->True

main: eventis set

多进程python_python -- 多进程相关推荐

  1. pyqt5多进程 python_Python 多进程大全

    Python 多线程 阅读本文需要4分钟 1 Python 多线程 多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸 ...

  2. python多进程_python多进程

    上一期我们讲了python中多线程的使用,忘记的小伙伴请戳链接复习,https://zhuanlan.zhihu.com/p/262638052. 还记得我们说到,多线程并不是真正的并发,只是充分利用 ...

  3. multiprocessing python_Python多进程运行——Multiprocessing基础教程1

    多进程是什么 多进程指的是操作系统同时支持多个处理器的能力.在支持多任务操作系统中,一个应用程序会被分解成多个独立运行的较小的程序.操作系统会将这些线程分配到多核处理器,以提升系统性能. 为什么需要多 ...

  4. python多进程_Python多进程实践

    本文重点探究以下几个内容: 创建进程Process 进程间数据传递Queue/Pipe/Value/Array/Manager 进程池Pool 创建进程Process 创建进程方式如下: 可以看出,P ...

  5. python 多进程 requests_python多进程(二)

    之前实现的数据共享的方式只有两种结构Value和Array.Python中提供了强大的Manager专门用来做数据共享的,Manager是进程间数据共享的高级接口. Manager()返回的manag ...

  6. php 自带多进程,php多进程实现

    php多进程实现 PHP有一组进程控制函数(编译时需要–enable-pcntl与posix扩展),使得php能在nginx系统中实现跟c一样的创建子进程.使用exec函数执行程序.处理信号等功能. ...

  7. python 彻底解读多线程与多进程_python 多进程与多线程浅析

    python多线程是伪多线程,同时间最多只有一个线程在执行,但这样并不代码python的多线程没有作用,对于IO密集型的系统,python的多线程还是能极大的提升性能- 关于python伪多线程可以去 ...

  8. linux 多线程 多进程 利用率,多进程与多线程的深度比较

    嵌入式Linux中文站,关于多进程和多线程,教科书上最经典的一句话是"进程是资源分配的最小单位,线程是CPU调度的最小单位".这句话应付考试基本上够了,但如果在工作中遇到类似的选择 ...

  9. php apache 多进程,php多进程 防止出现僵尸进程 如何 使 apache 成为 僵尸进程

    php pcntl 僵尸进程怎么产生的一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退 ...

最新文章

  1. c++ 宽搜(倒水)
  2. Batch Normalization原理及pytorch的nn.BatchNorm2d函数
  3. BGP策略路由的实现
  4. 相机内参中cx cy_Opencv中的两种去畸变函数
  5. VSTO学习笔记(四)从SharePoint 2010中下载文件
  6. 使用ETags减少Web应用带宽和负载
  7. chart.js 饼图显示百分比_Excel制作华夫饼图,其实很简单
  8. python利器-python利器去广告版
  9. 从设计心理学理解交互设计的原则
  10. 二进制的加减乘除实现
  11. qnx slm7.1(程序员开发手册-翻译)
  12. Fiddler环境配置/代理设置:电脑端/移动端/模拟器
  13. 解决video更多选项按钮点击无反应以及操控video标签的控制按钮
  14. JAXWS CXF WSDL first + MyEclipse + Maven Byron自學視頻03
  15. 《APUE》在Ubuntu上使用apue.h
  16. linux下脚本录制工具——script和scriptreplay
  17. Centos开机启动项
  18. Java百度鹰眼轨迹批量上传
  19. java jtable组件_java中jtable组件详解实例
  20. 比较好的python线上培训班

热门文章

  1. IDEA不愧为神器,结合Groovy脚本,简直无敌!
  2. 【redis】redis简介及基本数据结构的操作
  3. 帝国cms7.5多终端刷新单条内容信息时不起作用的解决方法
  4. pytorch kl散度学习笔记
  5. libtorch 调用pytorch模型
  6. Visual Studio 调试(Dubug)模式下的“未定义标识符”
  7. elasticsearch(7)聚合统计-分组聚合
  8. Django 无法加载静态文件(js,css,image)解决办法
  9. Caffe学习系列(8):solver优化方法
  10. 生成tfreocrds