多进程Process

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多进程Process相关的知识,希望对你有一定的参考价值。

多进程旧式写法
from multiprocessing import Pool
def f(x):
    return x*x

if __name__ == ‘__main__‘:
    p = Pool(5)
    print(p.map(f,[1,2,3]))

  

多进程新式写法
from multiprocessing import Process
def run(num):
    print ‘this is ‘,num

for i in range(10):
    t = Process(target=run,args=(i,))
    t.start()

  

多进程-父子进程

from multiprocessing import Process
import os
def info(title):
        print title
        print ‘module name:‘,__name__
        if hasattr(os,‘getppid‘):
                print ‘parent process:‘,os.getppid()    #获取父进程PID
print ‘process id:‘,os.getpid()                 #获取子进程PID
def f(name):
        info(‘function f‘)  #子进程调用info函数
print ‘hello‘,name
if __name__ == ‘__main__‘:
        info(‘main line‘)   #父进程调用info函数
print ‘---------------‘
p = Process(target=f,args=(‘bob‘,))
        p.start()
        p.join()

  

进程数据共享

from multiprocessing import Process
li = []
def run(num):
    li.append(num)
    print ‘say hi‘,li

for i in range(10):
    t = Process(target=run,args=(i,))
    t.start()

print ‘ending‘,li

  

技术分享

进程各自持有一份数据,默认无法共享数据,要使进程间可以共享数据,则

#方法一,Array
from multiprocessing import Process,Array
#创建一个只包含数字类型的一个数组/列表,并且个数不可变
temp = Array(‘i‘, [11,22,33,44])

def Foo(i):
    temp[i] = 100+i
    for item in temp:
        print i,‘----->‘,item

for i in range(2):
    p = Process(target=Foo,args=(i,))
    p.start()

  

#方法二:manage.dict()共享数据
from multiprocessing import Process,Manager
manage = Manager()
dic = manage.dict()
def Foo(i):
    dic[i] = 100+i
    print dic.values()
for i in range(2):
    p = Process(target=Foo,args=(i,))
    p.start()
    p.join()

  

#方法3Queue
from multiprocessing import Process,Queue
def f(q,n):
    q.put([n,‘hello‘])
if __name__ == ‘__main__‘:
    q = Queue()
    for i in range(5):
        p = Process(target=f,args=(q,i))
        p.start()
    while True:
        print q.get()

  

#方法4,Manager
from multiprocessing import Process,Manager
def f(d,l):
    d[1] = ‘1‘
d[‘2‘] = 2
d[0.25] = None
l.reverse()     #反向列表
if __name__ == ‘__main__‘:
    manager = Manager()
    d = manager.dict()
    #d = {}
l = manager.list(range(10))
    #l = [0,1,2,4,5,6,7,8,9]
p = Process(target=f,args=(d,l))
    p.start()
    p.join()
    print d
    print l

  

技术分享


进程锁
from multiprocessing import Process, Array, RLock
def Foo(lock,temp,i):
    """
将第0个数加100
    """
lock.acquire()      #加锁
temp[0] = 100+i
    for item in temp:
        print i,‘----->‘,item
    lock.release()      #解锁

lock = RLock()
temp = Array(‘i‘, [11, 22, 33, 44])
for i in range(20):
    p = Process(target=Foo,args=(lock,temp,i,))
    p.start()

  

进程池

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

进程池中有两个方法:

  • apply
  • apply_async
from  multiprocessing import Process,Pool
import time

def Foo(i):
    time.sleep(2)
    return i+100

def Bar(arg):
    print arg

pool = Pool(5)
#print pool.apply(Foo,(1,))
#print pool.apply_async(func =Foo, args=(1,)).get()
for i in range(10):
    pool.apply_async(func=Foo, args=(i,),callback=Bar)

print ‘end‘
pool.close()
pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

  

from multiprocessing import Pool
import time
def f(x):
    print x*x
    #time.sleep(2)
return x*x

if __name__ == ‘__main__‘:
    pool = Pool(processes=2)   #同时5个进程
res_list = []
    for i in range(5):
        res = pool.apply_async(f,[i,])
        #res =  Process(target=f,args=[i,])
print ‘-----------‘,i
        res_list.append(res)
    for r in res_list:
        print ‘res_list:‘,r.get()

  

技术分享

 

 

协程

 

线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。

协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。

协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程;

greenlet

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
 
from greenlet import greenlet
 
 
def test1():
    print 12
    gr2.switch()
    print 34
    gr2.switch()
 
 
def test2():
    print 56
    gr1.switch()
    print 78
 
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

 

  

 

gevent

 

import gevent
 
def foo():
    print(‘Running in foo‘)
    gevent.sleep(0)
    print(‘Explicit context switch to foo again‘)
 
def bar():
    print(‘Explicit context to bar‘)
    gevent.sleep(0)
    print(‘Implicit context switch back to bar‘)
 
gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar),
])

 

  

 

遇到IO操作自动切换:

 

from gevent import monkey; monkey.patch_all()
import gevent
import urllib2

def f(url):
    print(‘GET: %s‘ % url)
    resp = urllib2.urlopen(url)
    data = resp.read()
    print(‘%d bytes received from %s.‘ % (len(data), url))

gevent.joinall([
        gevent.spawn(f, ‘https://www.python.org/‘),
        gevent.spawn(f, ‘https://www.yahoo.com/‘),
        gevent.spawn(f, ‘https://github.com/‘),
])

 

  

 

 

以上是关于多进程Process的主要内容,如果未能解决你的问题,请参考以下文章

python-- 多进程的基本语法 进程间数据交互与共享进程锁和进程池的使用

进程锁和进程池

进程数据隔离,守护进程,锁,信号量和事件

基于Zookeeper实现多进程分布式锁

QEMU多进程(Multi-process QEMU)及vfio-user应用

QEMU多进程(Multi-process QEMU)及vfio-user应用