Python中的多进程

一、python并发编程之多进程

1、multiprocessing模块介绍(

from multiprocessing import Process

2、Process类的介绍

 1 创建进程的类:

Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)

强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号


2参数介绍:

1 group参数未使用,值始终为None
2 
3 target表示调用对象,即子进程要执行的任务
4 
5 args表示调用对象的位置参数元组,args=(1,2,'egon',)
6 
7 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
8 
9 name为子进程的名称

3方法介绍:

 1 p.start():启动进程,并调用该子进程中的p.run() 
 2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法  
 3 
 4 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
 5 p.is_alive():如果p仍然运行,返回True
 6 
 7 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程  

4属性介绍:

1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
2 
3 p.name:进程的名称
4 
5 p.pid:进程的pid
6 
7 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
8 
9 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)

3、Process类的使用

注意:在windows中Process()必须放到# if __name__ == '__main__':下

由于Windows没有fork,多处理模块启动一个新的Python进程并导入调用模块。 
如果在导入时调用Process(),那么这将启动无限继承的新进程(或直到机器耗尽资源)。 
这是隐藏对Process()内部调用的原,使用if __name__ == “__main __”,这个if语句中的语句将不会在导入时被调用。

开启子进程的方法一:

开启子进程的方法二:

 

进程内存空间彼此隔离的例子:

 小练习:把之前所学的socket通讯变成并发的形式:

服务端:
 1 # _*_coding:utf-8_*_
 2 __author__ = 'huying'
 3 
 4 from socket import *
 5 
 6 from multiprocessing import Process
 7 
 8 server=socket(AF_INET,SOCK_STREAM)
 9 server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
10 server.bind(('127.0.0.1',8080))
11 server.listen(5)
12 
13 def talk(conn,client_addr):
14     while True:
15         try:
16             msg=conn.recv(1024)
17             if len(msg)==0:break
18             conn.send(msg.upper())
19         except Exception:
20             break
21 
22 if __name__ == '__main__':
23     while True:
24         conn,client_addr=server.accept()
25         p=Process(target=talk,args=(conn,client_addr))
26         p.start()
View Code
客户端 :
# _*_coding:utf-8_*_
__author__ = 'huying'

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))

while True:
    msg=input('>>>:').strip()
    if len(msg)==0:continue
    phone.send(msg.encode('utf-8'))
    data=phone.recv(1024)
    print(data)
phone.close()
View Code

Process对象的join方法

  • join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。

    如下:

     1 # _*_coding:utf-8_*_
     2 __author__ = 'huying'
     3 
     4 
     5 
     6 from multiprocessing import Process
     7 import time
     8 
     9 
    10 def task(name):
    11     print('%s is running.'%name)
    12     time.sleep(3)
    13     print('%s is done.'%name)
    14 
    15 if __name__ == '__main__':
    16     p=Process(target=task,args=('子进程1',))
    17     p.start()
    18     p.join()
    19     print('')
    View Code

    2、 

  

 1 from multiprocessing import Process
 2 import time
 3 def task(name,n):
 4     print('%s is running.'%name)
 5     time.sleep(n)
 6     print('%s is done.'%name)
 7 if __name__ == '__main__':
 8     p1=Process(target=task,args=('子进程1',1))
 9     p2=Process(target=task,args=('子进程2',2))
10     p3=Process(target=task, args=('子进程3', 3))
11 
12     start_time=time.time()
13     p1.start()
14     p2.start()
15     p3.start()
16 
17     p1.join()
18     p2.join()
19     p3.join()
20 
21     stop_time=time.time()
22     print('',(stop_time-start_time))
View Code

3、

 1 from multiprocessing import Process
 2 import time
 3 def task(name,n):
 4     print('%s is running.'%name)
 5     time.sleep(n)
 6     print('%s is done.'%name)
 7 
 8 if __name__ == '__main__':
 9     p1=Process(target=task,args=('子进程1',1))
10     p2=Process(target=task,args=('子进程2',2))
11     p3=Process(target=task,args=('子进程3',3))
12 
13     start=time.time()
14 
15     p1.start()
16     p1.join()
17     p2.start()
18     p2.join()
19     p3.start()
20     p3.join()
21 
22     stop=time.time()
23     print('',(stop-start))
View Code

4、  3的精简版

 1 from multiprocessing import Process
 2 import time
 3 def task(name,n):
 4     print('%s is running.'%name)
 5     time.sleep(n)
 6     print('%s is done.'%name)
 7 
 8 if __name__ == '__main__':
 9     p_1=[]
10     start=time.time()
11     for i in range(1,4):
12         p=Process(target=task,args=('子进程%s'%i,i))
13         p_1.append(p)
14         p.start()
15 
16     for p in p_1:
17         p.join()
18 
19     stop=time.time()
20     print('',(stop-start))
View Code

了解知识点:

 1 #进程对象的其他方法一:terminate,is_alive
 2 from multiprocessing import Process
 3 import time
 4 import random
 5 
 6 class Piao(Process):
 7     def __init__(self,name):
 8         self.name=name
 9         super().__init__()
10 
11     def run(self):
12         print('%s is piaoing' %self.name)
13         time.sleep(random.randrange(1,5))
14         print('%s is piao end' %self.name)
15 
16 
17 p1=Piao('egon1')
18 p1.start()
19 
20 p1.terminate()#关闭进程,不会立即关闭,所以is_alive立刻查看的结果可能还是存活
21 print(p1.is_alive()) #结果为True
22 
23 print('开始')
24 print(p1.is_alive()) #结果为False
25 
26 terminate与is_alive
View Code
 1 from multiprocessing import Process
 2 import time
 3 import random
 4 class Piao(Process):
 5     def __init__(self,name):
 6         # self.name=name
 7         # super().__init__() #Process的__init__方法会执行self.name=Piao-1,
 8         #                    #所以加到这里,会覆盖我们的self.name=name
 9 
10         #为我们开启的进程设置名字的做法
11         super().__init__()
12         self.name=name
13 
14     def run(self):
15         print('%s is piaoing' %self.name)
16         time.sleep(random.randrange(1,3))
17         print('%s is piao end' %self.name)
18 
19 p=Piao('egon')
20 p.start()
21 print('开始')
22 print(p.pid) #查看pid
23 
24 name与pid
View Code
原文地址:https://www.cnblogs.com/huyingsakai/p/9295211.html