多进程

os模块中fork()Unix/Linux操作系统下多进程函数。

子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程。

 

import os

print('Process (%s) start...' % os.getpid())

 

pid = os.fork()

if pid == 0:

    print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))

else:

    print('I (%s) just created a child process (%s).' % (os.getpid(), pid))

 

运行结果如下:

Process (876) start...

I (876) just created a child process (877).

I am child process (877) and my parent is 876.

 

Multiprocessing

multiprocessing模块是跨平台版本的多进程模块。

 

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('Child process will start.')

    p.start()  #用start()方法启动

    p.join()   #join()方法可以等待子进程结束后再继续往下运行

    print('Child process end.')

执行结果如下:

Parent process 928.

Process will start.

Run child process test (929)...

Process end.

 

 

Pool

如果要启动大量的子进程,可以用进程池的方式批量创建子进程:

from multiprocessing import Pool

import os, time, random

 

def long_time_task(name):

    print('Run task %s (%s)...' % (name, os.getpid()))

    start = time.time()

    time.sleep(random.random() * 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(4)

    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.')

执行结果如下:

Parent process 669.

Waiting for all subprocesses done...

Run task 0 (671)...

Run task 1 (672)...

Run task 2 (673)...

Run task 3 (674)...

Task 2 runs 0.14 seconds.

Run task 4 (673)...

Task 1 runs 0.27 seconds.

Task 3 runs 0.86 seconds.

Task 0 runs 1.41 seconds.

Task 4 runs 1.91 seconds.

All subprocesses done.

对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。

由于Pool的默认大小是CPU的核数,而task 4要等待前面某个task完成后才执行。

 

控制子进程的输入和输出

很多时候,子进程并不是自身,而是一个外部进程。我们创建了子进程后,还需要控制子进程的输入和输出。

省略。。。。。

 

进程间通信

Process之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。

 

我们以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:

from multiprocessing import Process, Queue

import os, time, random

 

# 写数据进程执行的代码:

def write(q):

    print('Process to write: %s' % os.getpid())

    for value in ['A', 'B', 'C']:

        print('Put %s to queue...' % value)

        q.put(value)

        time.sleep(random.random())

 

# 读数据进程执行的代码:

def read(q):

    print('Process to read: %s' % os.getpid())

    while True:

        value = q.get(True)

        print('Get %s from queue.' % value)

 

if __name__=='__main__':

    # 父进程创建Queue,并传给各个子进程:

    q = Queue()

    pw = Process(target=write, args=(q,))

    pr = Process(target=read, args=(q,))

    # 启动子进程pw,写入:

    pw.start()

    # 启动子进程pr,读取:

    pr.start()

    # 等待pw结束:

    pw.join()

    # pr进程里是死循环,无法等待其结束,只能强行终止:

    pr.terminate()

 

运行结果如下:

Process to write: 50563

Put A to queue...

Process to read: 50564

Get A from queue.

Put B to queue...

Get B from queue.

Put C to queue...

Get C from queue.

 


转载于:https://my.oschina.net/zengjs275/blog/651003

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值