python 多进程

python中的多进程

1.用fork创建进程(Linux中使用)

1 import os
2 #fork函数,只在Unix/Linux/Mac上运⾏,windows不可以
3 pid = os.fork()
4 if pid == 0:
5   print('hello--1')
6 else:
7   print('hello--2')

程序走到os.fork()时,会创建出一个子进程,并将父进程中的所有信息复制到子进程中,父进程和子进程都会从os.fork()中得到一个返回值,子进程中这个返回值是0,而父进程中这个返回值就是子进程的id号

注意:fork被调用时会返回两个值,一个是代表子进程的0,另一个是代表父进程的子进程id号

父进程、子进程的执行顺序没有规律,完全取决于系统的调度算法

获取进程id号:

    获取当前进程的进程id号:   getpid()

    获取父进程的进程id号:   getppid()

 

多进程对于全局变量的影响:

     多进程中,每个进程所有的数据都拥有一份(包括全局变量),不受影响

      主要是因为多进程的实质是每个进程在cpu的各个核心上轮流占用,每一时刻在cpu的各个核心上都只有一个进程

 

2.用multiprocessing来创建多进程

 1 from multiprocessing import *
 2 import os
 3 
 4 def run_process(num):
 5     print("子进程%d--->%d     它的父进程--->%d"%(num,os.getpid(),os.getppid()))
 6 
 7 def main():
 8     # 开始搞5个进程
 9     for num in range(5):
10         # Process中常用的的参数有  target 、 args 、 kwargs 、name    其中name意为给这个进程命一个别名,如果不写name参数,则默认为name = Process-N   N为一个递增的整数
11         p = Process(target=run_process,args=(num,))
12         p.start()
13         # p.join()   join()的作用是等待子进程结束再往下走,通常用于进程间的同步
14         # join(timeout)  join()中可接受一个超时参数,以确定它要等待多少秒的时间
15 
16 if __name__ == "__main__":
17     main()

其运行的结果如下:

运行结果中子进程的编号并没有遵从for循环中的0,1,2,3,4的顺序是因为子进程的运行是没有顺序而言的,它取决于系统的调度算法

3.通过Process的子类来创建进程

 1 from multiprocessing import Process
 2 import os
 3 
 4 #  创建一个Process的子类
 5 class process_children(Process):
 6     def __init__(self, num):
 7         # 这里主要是因为Process类中也有__init__方法
 8         # 如果不加不写这句话就相当于重写了__init__方法,然而这并不是我们想要的结果
 9         # 这句话的作用就是将子类中接收到的参数再传给Process父类
10         Process.__init__(self)
11         self.num = num
12     
13     # 这个run方法一定要定义,且必须写成run ,因为这个函数中的代码决定了创建的子进程会怎样执行
14     def run(self):
15         print("%s ---> 当前进程id为%s ,父进程为%s"%(self.num, os.getpid(), os.getppid()))
16 
17 def main():
18     while True:
19         for num in range(5):
20             # 如果我们用Process的子类来创建进程,直接将需要传递的参数传递给类就可以了
21             p = process_children(num)
22             p.start()
23             # p.join()
24 
25 if __name__ == "__main__":
26     main()

4.进程池(代码在Ubuntu下测试)

 1 from multiprocessing import Pool
 2 import os
 3 
 4 def func(num):
 5     print("%d---> 当前进程为:%d,它的父进程为:%d"%(num, os.getpid(), os.getppid()))
 6 
 7 #开启一个进程池,池中最大的进程数为3
 8 #最大进程数的意思是统一时刻在这个进程池中的最多的进程数量是3
 9 #如果进程池中有进程结束,才会为等待的进程创建出新的进程
10 po=Pool(3)
11 
12 def main():
13     for i in range(0,10):
14         # apply_async为非阻塞模式     apply为阻塞模式   
15         po.apply_async(func, args=(i,))
16     print("start")
17     #close一定要放在join的前面 
18     po.close()
19     #join的作用是让主进程等待子进程执行完毕
20     po.join()
21     print("finish")
22 
23 if __name__ == "__main__":
24     main()

运行结果:

要点:最后的close() 一定要写在join() 的前面

5.进程间的通信------队列Queue        

  队列:first in first out(FIFO)---------先入先出

  栈:  first in last out(FILO)----------先入后出

      队列的使用:q = Queue(num)      num表示队列的最大长度

         写入:q.put(value)  ,  q.put_nowait()         读取:q.get() ,  q.get_nowait()

         判断:q.full()  ,    q.empty()   ,   q.qsize()

          q.get([block[timeout]])      

  1> 可以使用Queue在两个进程间传递数据,一个进程Queue.put() ,另一个进程Queue.get()

  2> 进程池中的进程间通信需要再导入multiprocessing中的Manager :   from multiprocessing impor Manager,Pool

   且使用Queue时需要用Manager()中的Queue,否则会报错---------->  q = Manager().Queue()         

 

猜你喜欢

转载自www.cnblogs.com/hgzero/p/8970211.html