python创建子进程,进程间利用队列通信,进程池的使用,队列加锁

注:如果未加入#coding:gbk或者#coding:utf-8,运行程序可能会报SyntaxError: Non-UTF-8 code starting with 错误.

python创建子进程

其中可以通过Process来构造一个子进程
p = Process(target=fun,args=(args))
再通过p.start()来启动子进程
再通过p.join()方法来使得子进程运行结束后再执行父进程

#coding:gbk
from multiprocessing import Process
import os

def run_proc(name):
    print('Run child process %s (%s)...' % (name, os.getpid()))

if __name__ == '__main__':
    print('Parent process %s.' % os.getpid())
    p = Process(target=run_proc, args=('test',))
    print('Process will start.')
    p.start()
    p.join()
    print('Process end.')
python利用进程池管理子进程

其中p.close()用来关闭进程池,进程池关闭后,就不能调用apply_async方法增加新的进程了。(一个池子里能同时运行多少个进程,取决于电脑cpu的数量,如果下面的代码中p=Pool(5)那么所有的子进程就可以同时进行,具体原因后续再研究)

#coding:gbk
from multiprocessing import Pool
import os, time


def long_time_task(name):
    print('Run task %s (%s)...' % (name, os.getpid()))
    start = time.time()
    time.sleep(3)
    end = time.time()
    print('Task %s runs %0.2f seconds.' % (name, (end - start)))


if __name__ == '__main__':
    print('Parent process %s.' % os.getpid())
    p = Pool()
    for i in range(5):
        p.apply_async(long_time_task, args=(i,))
    print('Waiting for all subprocesses done...')
    p.close()
    p.join()
    print('All subprocesses done.')

多个子进程间的通信用队列通信

队列中可以放任意格式的数据,实现多个子进程之间的通信,但是子进程跟父进程之间的通信需要使用multiprocess的Manager类 后面讲

#coding:gbk
from multiprocessing import Process, Queue
import os, time, random

# 写数据进程执行的代码:
def write(q):
    for value in ['A', 'B', 'C']:
        print ('Put %s to queue...' % value)
        q.put(value)
        time.sleep(random.random())

# 读数据进程执行的代码:
def read(q):
    while True:
        if not q.empty():
            value = q.get(True)
            print('Get %s from queue.' % value)
            time.sleep(random.random())
        else:
            break

if __name__== '__main__':
    # 父进程创建Queue,并传给各个子进程:
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 启动子进程pw,写入:
    pw.start()
    # 等待pw结束:
    pw.join()
    # 启动子进程pr,读取:
    pr.start()
    pr.join()
    # pr进程里是死循环,无法等待其结束,只能强行终止:
    print('所有数据都写入并且读完')

使用multiprocess的Manager类实现子进程与父进程之间的通信,以及多个子进程之间使用进程池的情况下通信也需使用multiprocess的Manager类

声明队列时使用manager.Queue()声明队列。(注意 读取的数据不一定完全,因为有的数据还未写入,读取任务就开始运行了)

# 将上面的代码main函数替换掉
if __name__ == '__main__':
    manager = multiprocessing.Manager()
    q = manager.Queue()
    p = Pool()
    pw = p.apply_async(write, args=(q,))
    time.sleep(0.5)
    pr = p.apply_async(read, args=(q,))
    p.close()
    p.join()
    print('数据读取完成')

可以利用进程锁,锁定同时只有一个进程对队列的值进行更改

使用lock = manager.Lock()声明一个锁,再进程执行的时候,将锁传入进程,可实现对队列的加锁和释放锁。

from multiprocessing import Process, Queue, Pool
import multiprocessing
import os, time, random

def write1(q, lock):
    lock.acquire()  # 加上锁
    for value in ['A', 'B', 'C']:
        print('Put %s to queue...' % value)
        q.put(value)
        time.sleep(random.random())
    lock.release()

def write2(q, lock):
    lock.acquire()  # 加上锁
    for value in ['D', 'E', 'F']:
        print('Put %s to queue...' % value)
        q.put(value)
        time.sleep(random.random())
    lock.release()

if __name__ == '__main__':
    q = Queue()
    manager = multiprocessing.Manager()
    lock = manager.Lock()
    pw1 = Process(target=write1, args=(q, lock))
    pw2 = Process(target=write2, args=(q, lock))
    # 启动子进程pw,写入:
    pw1.start()
    pw2.start()
    # pr.start()
    pw1.join()
    pw2.join()
    # pr.join()
    print('所有数据都写入并且读完')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值