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 import Process 5 import time 6 7 8 def f(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 import Process,Lock 8 9 def f(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 world 3 hello world 2 hello world 6 hello world 5 hello world 1 hello world 4 hello world 7 hello world 9 hello world 8
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异常。
(2) Pipe
Pipe方法返回(conn1, conn2)代表一个管道的两个端。Pipe方法有duplex参数,如果duplex参数为True(默认值),那么这个管道是全双工模式,也就是说conn1和conn2均可收发。duplex为False,conn1只负责接受消息,conn2只负责发送消息。
(3) Manager
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' 进程之间是不能直接通信的,需要第三方作为通信媒介 ''' '''以下是Queue实现数据传递代码''' from multiprocessing import Process,Queue def f1(q): q.put([22,'root','hello']) def f2(q): q.put([23,'admin','hello']) '''以下是Pipe实现数据传递代码''' from multiprocessing import Process,Pipe def f3(conn): conn.send([23,'admin1','hello']) def f4(conn): conn.send([24, 'root', 'hello']) '''以下是Manager实现数据共享代码''' from multiprocessing import Process,Manager def f(d,l,n): d[n] = n d['name'] = 'root' l.append(n) print(l) #以下是主程序 if __name__ == '__main__': print( '''