python进阶------进程线程(三)

python中的进程

 

1.multiprocessing模块

 

由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。

 

multiprocessing包是Python中的多进程管理包。与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。该进程可以运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。

 

1.1python的进程调用

# Process类调用

from multiprocessing import Process
import time
def f(name):

print('hello', name,time.ctime())
time.sleep(1)

if __name__ == '__main__':
p_list=[]
for i in range(3):
p = Process(target=f, args=('alvin:%s'%i,))
p_list.append(p)
p.start()
for i in p_list:
p.join()
print('end')

# 继承Process类调用
from multiprocessing import Process
import time

class MyProcess(Process):
def __init__(self):
super(MyProcess, self).__init__()
# self.name = name

def run(self):

print ('hello', self.name,time.ctime())
time.sleep(1)


if __name__ == '__main__':
p_list=[]
for i in range(3):
p = MyProcess()
p.start()
p_list.append(p)

for p in p_list:
p.join()

print('end')

1.2process类

 

构造方法:

 

Process([group [, target [, name [, args [, kwargs]]]]])

 

  group: 线程组,目前还没有实现,库引用中提示必须是None; 
  target: 要执行的方法; 
  name: 进程名; 
  args/kwargs: 要传入方法的参数。

 

实例方法:

 

  is_alive():返回进程是否在运行。

 

  join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。

 

  start():进程准备就绪,等待CPU调度

 

  run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。

 

  terminate():不管任务是否完成,立即停止工作进程

 

属性:

 

  daemon:和线程的setDeamon功能一样

 

  name:进程名字。

 

  pid:进程号。

1.3进程间的通信

1.3.1进程队列

from multiprocessing import Process, Queue
import queue

def f(q,n):
#q.put([123, 456, 'hello'])
q.put(n*n+1)
print("son process",id(q))

if __name__ == '__main__':
q = Queue() #try: q=queue.Queue()
print("main process",id(q))

for i in range(3):
p = Process(target=f, args=(q,i))
p.start()

print(q.get())
print(q.get())
print(q.get())

1.3.2 进程管道

from multiprocessing import Process, Pipe

def f(conn):
conn.send([12, {"name":"yuan"}, 'hello'])
response=conn.recv()
print("response",response)
conn.close()
if __name__ == '__main__':

parent_conn, child_conn = Pipe()

p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, 'hello']"
parent_conn.send("hello !")
p.join()

1.3.3manager

from multiprocessing import Process, Manager

def f(d, l,n):

    d[n] = n
    d["name"] ="alvin"
    l.append(n)

    #print("l",l)

if __name__ == '__main__':

    with Manager() as manager:

        d = manager.dict()

        l = manager.list(range(5))
        p_list = []

        for i in range(10):
            p = Process(target=f, args=(d,l,i))
            p.start()
            p_list.append(p)

        for res in p_list:
            res.join()

        print(d)
        print(l)

1.3.4进程池

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

from multiprocessing import Pool
import time

def foo(args):
time.sleep(1)
print(args)

if __name__ == '__main__':
p = Pool(5)
for i in range(30):
p.apply_async(func=foo, args= (i,))

p.close() # 等子进程执行完毕后关闭线程池
# time.sleep(2)
# p.terminate() # 立刻关闭线程池
p.join()

进程池中有以下几个主要方法:

  1. apply:从进程池里取一个进程并执行
  2. apply_async:apply的异步版本
  3. terminate:立刻关闭线程池
  4. join:主进程等待所有子进程执行完毕,必须在close或terminate之后
  5. close:等待所有进程结束后,才关闭线程池。
posted @ 2017-07-20 17:43  牛斌  阅读(156)  评论(0编辑  收藏  举报