进程、多进程、进程间数据交互、进程同步、进程池

多进程

  • 启用多进程,可以解决python调用计算机CPU多核运算的问题

启动一个进程

import multiprocessing
import time

def run(name):
    time.sleep(2)
    print('hello',name)

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

from multiprocessing import Process
import os

def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())#父进程ID
    print('process id:', os.getpid())#当前进程ID
    print("\n\n")

def f(name):
    info('\033[31;1mfunction f\033[0m')#子进程的info,子进程的PPID=主进程的PID
    print('hello', name)

if __name__ == '__main__':
    info('\033[32;1mmain process line\033[0m')#主进程的info
#在window,主进程的PPID=pycharm的PID
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
  • 每一个进程都是由一个父进程启动的

进程间数据交互

  • 不管哪种方式,都是找一个中间代理,相当于不同国家的人交流需要找一个翻译
  • 不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:

进程间数据交互(通信)的方式

1.Queues

  • 使用方法跟threading里的queue差不多。这里的queue不是线程中的,线程中的queue只能在创建线程的主进程之间由它的线程使用
from multiprocessing import Process, Queue
#用法和线程的queue是一样的,但这里引入的是进程的queue
def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()

2.Pipes管道

  • 管道实例化后会产生两个通道,分别交给两个进程
  • 通过send和recv来交互数据,这是一个双向的管道,child和parent可以互相收发
from multiprocessing import Process, Pipe

def f(conn):
    conn.send([42, None, 'hello'])
    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']"
    p.join()

3.Managers经理/代理

  • 以代理的方式在进程间共享字典或列表形式的数据
from multiprocessing import Process, Manager
import os
def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.append(os.getpid())
    print(l)

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()#生成一个字典,在多个进程间共享和传递

        l = manager.list(range(5))#生成一个列表含5个初始值,在多个进程间传递和共享
        p_list = []
        for i in range(10):
            p = Process(target=f, args=(d, l))
            p.start()
            p_list.append(p)
        for res in p_list:
            res.join()

        print(d)
        print(l)

进程同步LOCK

  • 进程不能操作同一块数据,那么进程锁的意义是什么?
  • 进程锁存在的意义是保证各进程在屏幕输出时不会乱
    比如:进程1,打印hello word 1,进程2打印hello word 2,没有锁,进程1的打印还没结束,进程2进来了,就可能造成混乱。(window上不会发生,linux上测试,2.7以下python)
from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    try:
        print('hello world', i)
    finally:
        l.release()

if __name__ == '__main__':
    lock = Lock()

    for num in range(10):
        Process(target=f, args=(lock, num)).start()

进程池

  • 进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
  • 进程池中有两个方法:
  • apply同步执行-串行
  • apply_async异步执行-并行
from  multiprocessing import Process, Pool
import time,os

def Foo(i):
    time.sleep(2)
    print('in process',os.getpid())
    return i + 100

def Bar(arg):
    print('-->exec done:', arg)

if __name__ == '__main__':
    pool = Pool(5)#同时允许5个进程进入进程池,其他进程挂起

    for i in range(10):
        pool.apply_async(func=Foo, args=(i,), callback=Bar)#callback回调函数
        # pool.apply(func=Foo, args=(i,))

    print('end')
    pool.close()#这里join一定是在close之后,且必须要加join,否则主进程不等待创建的子进程执行完毕
    pool.join()  # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

from concurrent.futures import ThreadPoolExecutor线程池必用模块

from concurrent.futures import ProcessPoolExecutor进程池必用模块

参考文档

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值