多进程的几种使用方法

Zss 发表于:

一.fork()

1.只能在mac和liunx,unix中使用,window不支持

2.ret = fork()          fork()会依次返回两个值,返回当前进程号,两个值分别为0和大于0,fork()会创建一个子进程,主进程的返回值为>0,子进程的值返回0

3.os.getpid()返回当前进程的pid,os.getppid()返回父进程的pid,pid一般最大值63535,意味可以运行这么多个进程

4.当执行过程中主进程先执行完,则程序结束,主进程不会等待子进程的结束

5.进程的执行顺序是不确定的,执行的顺序是由系统的调度算法来决定的

6.进程之间的全局变量,数据是不共享的,当主进程修改了全局变量,子进程再使用,全局变量是主进程修改前的值,进程之间的数据都是独立的不会被共享,

同一主机进程之间的通信可以使用文件的数据交换,不同主机之间的进程使用网络来通信

7.fock()炸弹,无限创建进程,系统很快就资源消耗完,系统奔溃

————————————————————————————————-

import os
while 1:
    os.fork()

————————————————————————————————–

import

ret = os.fock()

if ref > 0:

....  主进程所运行的程序

else:

.... 子进程所运行的程序

....  子进程和主进程都会运行的程序

二.multiprocessing中的process类

1.创建一个实例,p = Process() 意为创建一个进程,放置一个任务到此进程中

p = Process(target = test),,test意为一个函数或者方法,使用 p.start()来运行子进程

2.主进程会等待所有的子进程结束,主进程才会结束

3.p.join()   当子进程结束后才会执行join下面的代码,等待子进程结束这个过程称之为堵塞,当满足条件后叫做截堵塞,p.join(timeout)超时时间,当时间到了子进程还未结束则继续执行

4.p.terminate()   不管子进程任务是否完成,立即终止

5.给函数参数

p = Process(target=test,args=(a,b))

6.继承Process类  因为Process中有run()方法,在运行start()方法时调用了父类的run()方法,所以只需要重写父类的run()方法,这样子我在自己定义的类中编写各种方法来实现一个功能后,继承Process重写run()方法

from multiprocessing import Process
import time

class MyNewProcess(Process):
    def run(self):
        while True:
            print("---1----")
            time.sleep(1)


p = MyNewProcess()
p.start()

while True:
    print("---main----")
    time.sleep(1)

三.进程池,Pool

1.p = Pool(3)   创建三个进程放入到进程池中,可以不带参数,数值不是越大越好,当进程越大,所有进程依次轮回的时间和调度的时间就会要增加

2.p.apply_async(函数名字,(i,))  给进程池中添加任务,,函数名之后不需要加括号,单个参数为(参数,)

from multiprocessing import Pool
import os
import random
import time

def worker(num):
    for i in range(5):
        print("===pid=%d==num=%d="%(os.getpid(), num))
        time.sleep(1)

#3表示 进程池中对多有3个进程一起执行
pool = Pool(3)

for i in range(10):
    print("---%d---"%i)
    #向进程池中添加任务
    #注意:如果添加的任务数量超过了 进程池中进程的个数的话,那么不会导致添加不进入
    #       添加到进程中的任务 如果还没有被执行的话,那么此时 他们会等待进程池中的
    #       进程完成一个任务之后,会自动的去用刚刚的那个进程 完成当前的新任务
    pool.apply_async(worker, (i,))


pool.close()#关闭进程池,相当于 不能够再次添加新任务了
pool.join()#主进程 创建/添加 任务后,主进程 默认不会等待进程池中的任务执行完后才结束
            #而是 当主进程的任务做完之后 立马结束,,,如果这个地方没join,会导致
            #进程池中的任务不会执行

3.pool.close()  关闭进程池,相当于 不能够再次添加新任务了,当进程池创建后就可以添加任务进去了,但是close后就相当于关闭了,无法再加入任务

4.使用pool()一般让主进程等待子进程去执行完任务,process可以让子进程和主进程同时执行任务

5.pool.apply()是阻塞的方式,相当于一个进程运行,再添加任务完时会阻塞在这里,一定要等待前一个任务运行完后才会再次添加新的任务,而pool.apply_async(),为非阻塞的方式添加,不会等之前的进程完成才会添加任务

6.map()

函数原型:

map(func, iterable[, chunksize=None])

Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到返回结果。
注意,虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程。