多进程和进程间的通信

一、多进程

多进程合适计算密集型的应用,以下给出python中两个模块:subprocess和multiprocessing。

1、subprocess

subprocess是用来执行其他的可执行程序的,即执行外部命令。 它是os.fork() 和 os.execve() 的封装。 它启动的进程不会把父进程的模块加载一遍。使用subprocess的通信机制比较少,通过管道或者信号机制。

简而言之,使用subproces来为外部的可执行程序创建多进程比较方便。

具体的代码如下:

import subprocess
import os

with open("pair.txt") as pair:
    s = []
    for line in pair:
        line_str = line.split()
        print(line_str[0], line_str[1])
        print("computing the Home between %s and %s"%(line_str[0], line_str[1]))
        pro = subprocess.Popen(['./Homo2.exe', line_str[0], line_str[1]])
        s.append(pro)
        if len(pro) >= 4:
            s[0].wait()
            s.pop(0)


2、 multiprocessing 

multiprocessing用来执行python的函数,它启动的进程会重新加载父进程的代码。可以通过Queue、Array、Value等对象来通信。简而言之,当我们需要为python自己的函数创建多进程的时候,使用multiprocessing比较方便。

具体代码如下:

import multiprocessing
import time

def run(name):
    time.sleep(2)
    print('%s is sleeping...'%name)

def main():
    for i in range(10):
        p = multiprocessing.Process(target=run, args=('Bob %s'%i,))
        p.start()

if __name__ == '__main__':
    main()

二、进程间的通信
1、由于进程之间PCB是相互独立的,因此各个进程之间想要实现相互通信的功能,就需要一些通信机制,常见的通信机制有:管道(pipe)、消息队列(message queue)、
共享内存(shared memory)和套接字(socket)。
2.管道(pipe)
(1)管道有双向的,也有单向的;
(2)管道的创建:
pipe = multiprocessing.Pipe() 双向的管道;
pipe = multiprocessing.Pipe(duplex=False) 双向的管道,pipe[0]为接收端,pipe[1]为发送端;
(3)双管道代码
from multiprocessing import Process,Pipe

def proc1(pipe):
    s = 'Hello World'
    pipe.send(s)

def proc2(pipe):
    while True:
        print(pipe.recv())

def main():
    pipe = Pipe()
    p1 = Process(target=proc1, args=(pipe[0],))
    p2 = Process(target=proc2, args=(pipe[1],))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

if __name__ == '__main__':
    main()

(4)单管道代码
from multiprocessing import Process,Pipe

def proc1(pipe):
    s = 'Hello World'
    pipe.send(s)

def proc2(pipe):
    while True:
        print(pipe.recv())

def main():
    pipe = Pipe(duplex=False)
    p1 = Process(target=proc1, args=(pipe[1],)) #pipe[1]为发送端
    p2 = Process(target=proc2, args=(pipe[0],)) #pipe[0]为接收端
    p1.start()
    p2.start()
    p1.join()
    p2.join()

if __name__ == '__main__':
    main()

3、队列(queue)
(1)代码实现
from multiprocessing import Process,Queue,Lock

def add(q,a,b,lock):
    lock.acquire()
    li = range(a,b)
    lock.release()
    q.put(li)
    for item in li:
        print(item)

def main():
    lock = Lock()
    L = [1, 2, 3]
    q = Queue()
    p1 = Process(target=add, args=(q,10,20,lock))
    p2 = Process(target=add, args=(q,20,30,lock))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    L += q.get()
    L += q.get()
    print(L)

if __name__ == '__main__':
    main()

(2)熟悉使用队列的方法,例如:q.get(),q.put()等函数
 
4、共享内存(manager)
(1)Manager是专门用作数据共享的,其支持的数据类型有很多,例如:Value、Array、List、Queue、dict等
(2)代码实现:利用manager共享dict和list
from multiprocessing import Process, Manager
import os

def run(dic, l):
    dic[os.getpid()] = os.getpid() #字典
    l.append(os.getpid()) #列表

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=run, args=(d,l))
            p.start()
            p_list.append(p)
    
        for p in p_list:
            p.join()

        print(l)
        print(d)

5、套接字(socket)
利用套接字实现进程之间的通信,常见的例子是:TCP/IP中的服务器端和客户端,这里不再赘述,请参见前面的博客。
 
 



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值