多进程入门

本部分内容是对“莫烦的Python:多进程”部分的总结。

网址:https//morvanzhou.github.io/tutorials/python-basic/multiprocessing/

1.Multiprocessing

充分利用多核优势,可以将任务平均分配给多核,每个核有自己的运算空间和运算能力。

弥补多线程的劣势,即GIL,避免只运行一个线程,这里可以运行多个线程。

Python中的中多进程和多线程的线程使用差不多。

2.创建进程

(1)和螺纹类似

importmultiprocessing as mp

importthreading as td

defjob(A,d):

    打印('AAAAA')

t1 = td.Thread(target = job,args =(1,2))

p1 = mp.Process(target = job,args =(1,2))

t1.start()

p1.start()

t1.join()

p1.join()

(2)多进程

importmultiprocessing as mp

defjob(A,d):

    打印('AAAAA')

if__name __ =='__ main__'://一定要写

    p1 = mp.Process(target = job,args =(1,2))// args =(1,2)是job函数的输入参数。

    p1.start()

p1.join()

对于视窗系统,直接运行出来结果。对于苹果的系统,要在终端运行,否则用IDLE会报错。若用其它编译器,如Pycharm则不会报错。

3.存储进程输出队列

队列的功能是将每个核或线程的运算结果放在队里中,等到每个线程或核运行完毕后再从队列中取出结果,继续加载运算。原因很简单,多线程调用的函数不能有返回值,所以使用队列存储多个线程运算的结果。

importmultiprocessing as mp

defjob(Q):

    RES = 0

    对于范围内的I(1000):

        RES + = I + I ** 2 + I 3 **

    q.put(RES)#queue

if__name __ =='__ main__':

    q = mp.Queue()

    p1 = mp.Process(target = job,args =(q,))

    p2 = mp.Process(target = job,args =(q,))

    p1.start()

    p2.start()

    p1.join()

    p2.join()

    res1 = q.get()

    res2 = q.get()

    打印(RES1 + RES2)

得出结果的步骤和2一样,结果是:

499667166000

4.多线程和多进程效率的对比

对比下多进程,多线程和什么都不做时的消耗时间,看看哪种方式更有效率。

importmultiprocessing as mp

importthreading as td

importtime 用来计算时间

defjob(Q):

    res = 0

    对于范围内的我(1000000):

        res + = i + i ** 2 + i ** 3

q.put(RES)#queue

#多进程

defmulticore():

    q = mp.Queue()

    p1 = mp.Process(target = job,args =(q,))

    p2 = mp.Process(target = job,args =(q,))

    p1.start()

    p2.start()

    p1.join()

    p2.join()

    res1 = q.get()

    res2 = q.get()

print('multicore:',res1 + res2)

#多线程

defmultithread():

    q = mp.Queue()#thread 可以放入process 同样的队列

    t1 = td.Thread(target = job,args =(q,))

    t2 = td.Thread(target = job,args =(q,))

    t1.start()

    t2.start()

    t1.join()

    t2.join()

    res1 = q.get()

    res2 = q.get()

print('multithread:',res1 + res2)

#正常

defnormal():

    res = 0

    for _ in range(2):

        对于范围内的我(1000000):

            res + = i + i ** 2 + i ** 3

    打印( '正常:',RES)

if__name__ =='__ main__':

    st = time.time()

    正常()

    st1 = time.time()

    print('normal time:',st1-st)

    多线程()

    st2 = time.time()

    print('multithread time:',st2-st1)

    多核()

print('multicoretime:',time.time() - st2)

结果显示:运行花的时间满足:多进程<普通<多线程。

5.进程池池多重

进程池就是我们将所要运行的东西,放到池子里,巨蟒会自行解决多进程的问题,如分配进程和结果。

importmultiprocessing as mp

#之前是不能将结果返回的,只能将结果放在队列队列中。现在,使用池后可以有返回值。

defjob(X):

     返回x * x

defmulticore():

     pool = mp.Pool(processes = 2)#自定义需要的核数量。

     res = pool.map(job,range(10))#Pool和之前的Process的不同点是丢向池的函数有返回值,而Process的没有返回值。接下来用map()获取结果,在地图中()中需要放入函数和需要迭代运算的值,然后它会自动分配给CPU核,返回结果。

     打印(RES)

#Pool除了地图()外,还有可以返回结果的方式,那就是apply_async()。apply_async()中只能传递一个值,它只会放入一个核进行运算,但是传入值时要注意是可迭代的,所以在传入值后需要加逗号,同时需要用得到()方法获取返回值。

     res = pool.apply_async(job,(2,))

     打印(res.get())

#若用apply_async()输出多个迭代,可以将apply_async()放入迭代器中,定义一个新的multi_res。同样在取出值时需要一个一个取出来。

     multi_res = [pool.apply_async(job,(i,))for i in range(10)]

     print([multi_res中res的[res_get()])

如果__name__ =='__ main__':

     多核()

我们怎么知道Pool是否真的调用了多个核呢?我们可以把迭代次数增大些,然后打开CPU负载看下CPU运行情况。打开CPU负载(Mac):活动监视器> CPU> CPU负载(单击一下即可).Pool默认大小是CPU的核数,我们也可以通过在水池中传入处理参数即可自定义需要的核数量。

6.共享内存

共享变量可以以用全球性的。多进程中若想将全局变量的一个CPU运行结果传递给另一个CPU是行不通的,要用到共享内存,实现CPU之间的信息交流。

我们可以通过使用值数据存储在一个共享的内存表中。

importmultiprocessing as mp

#其中d 状语从句:参数用来设置数据类型的,d表示一个双精浮点类型,我表示一个带符号的整型。更多的形式请查看本页最后的表。可以被各CPU加载。

value1 = mp.Value('i',0)

value2 = mp.Value('d',3.14)

在Python的中的mutiprocessing中,有还有一个阵列类,可以和共享内存交互,来实现在进程之间共享数据。

array = mp.Array('i',[1,2,3,4])

这里的阵列和numpy的的中的不同,它只能是一维的,不能是多维的。同样和值一样,需要定义数据形式,否则会报错。

各参数代表的数据类型:

| 输入代码| Ç型| Python的类型| 最小大小(字节)|

| --------- | ------------------ | ----------------- | --------------------- |

| ''b'` | 签名字符| int | 1 |

| ''B'` | unsigned char | int | 1 |

| '' 你'| Py_UNICODE | 的Unicode字符| 2 |

| ''h'。| 签约短| int | 2 |

| '' H'` | unsigned short | int | 2 |

| '' 我'| signed int | int | 2 |

| '' 我'| unsigned int | int | 2 |

| '' 我'| 签名长| int | 4 |

| '' L '' | 无符号长| int | 4 |

| '' Q'。| 签长久| int | 8 |

| '' Q'` | unsigned long long | int | 8 |

| ` 'F'。| 漂浮| 漂浮| 4 |

| ` 'd' | 双| 漂浮| 8 |

7. 进程锁

不加进程锁。结果显示两个进程出现冲突,相互抢着使用共享内存。

将多处理导入为熔点

进口时间

def job(v,num):

    for_ in range(5):

       time.sleep(0.1)#暂停0.1 秒,让输出效果更明显

       v.value + = num#v.value 获取共享变量值

       print(v.value,end =“”)      

def multicore():

    v = mp.Value('i',0)#定义共享变量

    p1 = mp.Process(target = job,args =(v,1))

    p2 = mp.Process(target = job,args =(v,3))#设定不同的数字看如何抢夺内存

   p1.start()

   p2.start()

   p1.join()

   p2.join()   

如果__name__ =='__ main__':

   多核()

加进程锁

importmultiprocessing as mp

importtime

defjob(v,num,l ):#多个l ,所以锁住。

    l.acquire()#锁住

    for _ in range(10):

        time.sleep(0.1)

        v.value + = num

        打印(v.value)

    l.release()#释放

defmulticore():

    l = mp.Lock()#定义一个进程锁

    v = mp.Value('i',0)#定义共享内存

    p1 = mp.Process(target = job,args =(v,1,l))#锁定传入

    p2 = mp.Process(target = job,args =(v,3,l))

    p1.start()

    p2.start()

    p1.join()

    p2.join()

if__name__ =='__ main__':

    多核()

不加1                  

           4 2

           5 3

           8 4

           9 5

           12 8

           13 11

           16 14

           17 17

           20 20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值