文档章节

多进程

曾劲松
 曾劲松
发布于 2016/03/31 19:56
字数 814
阅读 6
收藏 0

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.

 


© 著作权归作者所有

上一篇: 多线程
下一篇: IO之串行化
曾劲松
粉丝 5
博文 200
码字总数 141434
作品 0
武汉
私信 提问

暂无文章

CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
10
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0
PHP+Ajax微信手机端九宫格抽奖实例

PHP+Ajax结合lottery.js制作的一款微信手机端九宫格抽奖实例,抽奖完成后有收货地址添加表单出现。支持可以设置中奖概率等。 奖品列表 <div class="lottery_list clearfix" id="lottery"> ......

ymkjs1990
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部