Python多进程

Python多进程

1.Process类

Process类是用来创建进程的
class multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)其中group应该永远为空,它的存在仅仅是与threading.Thread兼容,threading,Thread也有一个group的参数,不过现在也没有使用,保留到以后线程组实现了以后再用。target,传入一个函数这样的可调用对象,执行run方法的时候会执行这个函数。name就是定义进程的名字,如果这个参数不定义,则默认名字为Process-x (x是序号)。args是个参数元组,kwargs是个字典,都是传给target作为参数。参数daemon可以设置进程是否是守护进程,如果为空,这个参数将会从父进程继承。当一个进程退出的时候,它会尝试去终止所有的daemon子进程,一个daemon进程不允许创建子进程,否则的话当父进程退出的时候这些子进程就变为孤儿进程了.daemon进程的使用场景是:需要一个始终运行的进程,用来监控其他服务的运行情况,或者发送心跳包或者类似的东西,创建了这个进程以后就不用管他了,它会随着主进程的退出而退出。进程创建以后,可以通过访问属性的方式进行设置:

p = multiprocessing.Process(target = worker, args = (3,))
p.daemon = True

   存在以下接口:run()、start()、join()、is_alive()、terminate() ,接口相对都比较简单,类似于线程,下面是一个创建进程的简单例子

import multiprocessing
import time

def worker(interval):
    print("CCD")

if __name__ == "__main__":
    p = multiprocessing.Process(target = worker, args = (3,) ,name = "ccd")
    print("p.name:",p.name)
    p.start()

 2.Lock(锁)

Lock.acquire () 获得锁   Lock.release() 释放锁,RLock是可重入锁 RLock.acquire()获得锁  RLock.release() 释放锁

 3.Semaphore(信号量)

Semphore,是一种带计数的同步机制,当调用release时,增加计算,当acquire时,减少计数,当计数为0时,自动阻塞,等待release被调用。可以用来控制对共享资源的访问数量,例如池的最大连接数。例子如下:

import multiprocessing
import time

def worker(s, i):
    s.acquire()
    print(multiprocessing.current_process().name + "acquire");
    time.sleep(i)
    print(multiprocessing.current_process().name + "release\n");
    s.release()

if __name__ == "__main__":
    s = multiprocessing.Semaphore(2)
    for i in range(5):
        p = multiprocessing.Process(target=worker,args=(s,i))
        p.start()

 结果如下:  我们信号量初始化为2,所以创建的第三个进程没法执行,只能阻塞,直到有进程释放信号量。

Process-4acquire
Process-3acquire
Process-3release

Process-2acquire   
Process-4release

Process-1acquire
Process-1release

Process-5acquire
Process-2release

Process-5release

4.Event(事件)

 类似于线程的Event,主要接口有set()、clear()、wait()

5.Pipe(管道)

Pipe方法返回(conn1,conn2)这样一组Connetion对象,Pipe方法有duplex参数,如果duplex参数为True(默认值),那么这个管道是全双工模式,也就是说conn1和conn2均可收发。duplex为False,conn1只负责接受消息,conn2只负责发送消息。

例子:

import multiprocessing
import time

def proc1(pipe):
    while True:
        for i in range(5):
            print("send: %s" % (i))
            pipe.send(i)
            time.sleep(1)

def proc2(pipe):
    while True:
        print("rev:", pipe.recv())
        time.sleep(1)

if __name__ == "__main__":
    pipe = multiprocessing.Pipe()
    p1 = multiprocessing.Process(target=proc1, args=(pipe[0],))
    p2 = multiprocessing.Process(target=proc2, args=(pipe[1],))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

结果如下:

send: 0
rev: 0
send: 1
rev: 1
send: 2
rev: 2
....

 6.Queue(队列)

Queue是一种进程安全的共享数据结构,进程之间可以使用队列进行数据共享,队列是由管道和一些锁/信号量来实现的,当一个进程将数据放入队列中,就会起一个线程将对象从buffer中放到pipe中来。主要的接口有put()、get()
对于put()接口是将元素放入队列中,其中有两个可选参数block,timeout。如果block为True同时timeout为none(默认值),则会一直阻塞直到队列中空闲。如果timeout不为none,
是个正数,则会阻塞timeout秒,如果超时的时候队列还是满的,则就抛出queue.Full异常。如果block为false,如果队列空闲,则put操作直接将元素放入队列中,如果队列满,则直接抛出queue.Full异常。简单的说,就是put操作将元素放入队列中,如果采用非阻塞方式,队列有空闲则直接放入,否则抛出异常。而阻塞方式,如果队列满了,还会阻塞等待,如果指定了超时时间,则只会阻塞超时时间这么久,否则一直阻塞下去,直到队列有空闲
get()接口是从队列中读取并移除一个元素, 它也有block,timeout两个数据。只不过是在队列为空的时候阻塞,通过block参数决定取数据的时候队列为空的情况阻塞不阻塞。

import multiprocessing

def writer_proc(q):      
    try:         
        q.put(1, block = False) 
    except:         
        pass   

def reader_proc(q):      
    try:         
        print q.get(block = False) 
    except:         
        pass

if __name__ == "__main__":
    q = multiprocessing.Queue()
    writer = multiprocessing.Process(target=writer_proc, args=(q,))  
    writer.start()   

    reader = multiprocessing.Process(target=reader_proc, args=(q,))  
    reader.start()  

    reader.join()  
    writer.join()

 

结果如下:

 1

 

posted @ 2018-01-12 22:52  BGPY  阅读(252)  评论(0编辑  收藏  举报