python之多进程

简介: 要让python实现多进程「multiprocessing」。我们先来了解操作系统相关知识。Unix 和 Linux 操作系统提供了一个 fork() 函数系统调用,它非常特殊。

要让python实现多进程「multiprocessing」。我们先来了解操作系统相关知识。
Unix 和 Linux 操作系统提供了一个 fork() 函数系统调用,它非常特殊。普通的函数,调用一它次,执行一次,但是 fork() 函数调用一次执行两次,因为操作系统自动把当前进程「称为父进程」复制了一份「称为子进程」,然后,分别在子进程和父进程中执行。
子进程永远返回0,而父进程返回子进程的 ID。这样做的理由是,一个父进程可以 fork() 多个子进程,所以父进程要记下所有子进程的 ID,而子进程只要调用 getppid() 就可以拿到父进程的 ID。
python中 os 模块封装了常见的系统调用,其中就包括 fork(),可以在python程序中轻松创建子程序:

import os

print('Process (%s) start ...' % os.getpid())
#Only work on Unix/linux/Mac
#不能在Windows平台上运行
pid = os.fork()
if pid == 0:
    print('I am child process (%) and my parent is %s.' % (os.getpid(),os.getppid()))
else:
    print('I (%) just created a child process (%).' % (os.getpid(),pid))

运行结果:

Process (876) start...
I (876) just created a child process (877).
I am child process (877) and my parent is 876.

由于 Windows 平台下没有 fork() 函数调用,所以代码没有办法在 Windows平台下运行。
有了 fork 调用,一个进程在接到任务的时候就可以复杂出来一个子进程来处理新任务,常见的 Apache 服务器就是由父进程监听端口,每当有新的 http 请求时,就 fork 出新的子进程来处理新的 http 请求。

multiprocessing「多进程」

如果你想写多进程的服务程序,Unix/Linux 平台最好了,当然也可以在 Windows 平台下来编写,因为 python 跨平台。multiprocessing 模块就是跨平台版本的多进程模块。
multiprocessing 模块提供了一个 Process 类来代表一个进程对象,下面一个例子用来演示启动一个子进程并等待结束的例子:

import os
from multiprocessing import Process

#子进程要执行的代码
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()#子程序开始执行
    p.join()
    print('Child process end.')
  • 创建子程序时,只需要传入一个执行的函数和函数的参数。
  • 创建一个 Procsess 实例,用 start() 方式开启,这样创建的进程比 fork 还简单。
  • join() 方法可以等jinc子进程执行完后再继续往下运行,通常用于进程之间的同步。
    Pool
    如果想要启动大量的子进程,可以用进程池的方式批量创建子进程。
import os,time,random
from multiprocessing import Pool

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 run %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 subprocess done...')
    p.close()
    p.join()
    print('All subprocess done')

执行结果:

Parent process 7600.
Waiting for all subprocess done...
Run task 0 (11392)...
Run task 1 (6432)...
Run task 2 (10768)...
Run task 3 (5116)...
Task 0 run 0.03 seconds.
Run task 4 (11392)...
Task 3 run 1.42 seconds.
Task 1 run 1.77 seconds.
Task 4 run 2.59 seconds.
Task 2 run 2.93 seconds.
All subprocess done

Process finished with exit code 0
  • 对Pool调用 join() 方法会等所用子进程执行完毕,调用 join() 之前一定要调用 close() 调用 close() 之后不能在有新的process
  • 程序的输出结果显示 task 0、1、2、3 是同时执行的,而 task 4 是等前四个执行完毕才执行,这是因为,进程池在我的电脑上是4。,因此最多执行四个进程,这是 Pool 有意设计的限制,并不是操作系统的限制,如果你改成
p = Pool(5)

就可以同时跑 5 个进程。

子进程

很多时候,子进程并不是本身,热是一个外部的进程。我们创建了子进程之后,还要控制进程的输入和输出。
subprocess 模块可以让我们非常方便的启动一个子进程,然后控制输入和输出。

这一部分未完待续


进程间的通信

Process 间肯定是要通信的,操作系统提供了很多机制来实现进程间的通信,python 中的 multiprocessing 模块包装了底层的机制,提供了 Queue、Pipes 等多种方法来交换数据。
我们以 Queue 为例,在父进程中创建两个子进程,一个往 Queue 里写数据,一个从 Queue 中读数据。

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

#写数据进程执行的代码
def write(q):
    print('Process to write : %s' % os.getpid())
    for value in ['A','B','C']:
        print('Put %s 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 read : 8416
Process to write : 12840
Put A queue...
Get A from queue.
Put B queue...
Get B from queue.
Put C queue...
Get C from queue.

Process finished with exit code 0
  • 在Windows 平台下实现多进程,用multiprocessing 模块
  • 进程间的通信是用 Queue 、Pipes 来进行的。
目录
相关文章
|
9天前
|
负载均衡 Java 调度
探索Python的并发编程:线程与进程的比较与应用
本文旨在深入探讨Python中的并发编程,重点比较线程与进程的异同、适用场景及实现方法。通过分析GIL对线程并发的影响,以及进程间通信的成本,我们将揭示何时选择线程或进程更为合理。同时,文章将提供实用的代码示例,帮助读者更好地理解并运用这些概念,以提升多任务处理的效率和性能。
|
21天前
|
消息中间件 安全 Kafka
Python IPC机制全攻略:让进程间通信变得像呼吸一样自然
【9月更文挑战第12天】在编程领域,进程间通信(IPC)是连接独立执行单元的关键技术。Python凭借简洁的语法和丰富的库支持,提供了多种IPC方案。本文将对比探讨Python的IPC机制,包括管道与消息队列、套接字与共享内存。管道适用于简单场景,而消息队列更灵活,适合高并发环境。套接字广泛用于网络通信,共享内存则在本地高效传输数据。通过示例代码展示`multiprocessing.Queue`的使用,帮助读者理解IPC的实际应用。希望本文能让你更熟练地选择和运用IPC机制。
38 10
|
17天前
|
监控 Ubuntu API
Python脚本监控Ubuntu系统进程内存的实现方式
通过这种方法,我们可以很容易地监控Ubuntu系统中进程的内存使用情况,对于性能分析和资源管理具有很大的帮助。这只是 `psutil`库功能的冰山一角,`psutil`还能够提供更多关于系统和进程的详细信息,强烈推荐进一步探索这个强大的库。
29 1
|
20天前
|
Python
惊!Python进程间通信IPC,让你的程序秒变社交达人,信息畅通无阻
【9月更文挑战第13天】在编程的世界中,进程间通信(IPC)如同一场精彩的社交舞会,每个进程通过优雅的IPC机制交换信息,协同工作。本文将带你探索Python中的IPC奥秘,了解它是如何让程序实现无缝信息交流的。IPC如同隐形桥梁,连接各进程,使其跨越边界自由沟通。Python提供了多种IPC机制,如管道、队列、共享内存及套接字,适用于不同场景。通过一个简单的队列示例,我们将展示如何使用`multiprocessing.Queue`实现进程间通信,使程序如同社交达人般高效互动。掌握IPC,让你的程序在编程舞台上大放异彩。
14 3
|
22天前
|
安全 开发者 Python
Python IPC大揭秘:解锁进程间通信新姿势,让你的应用无界连接
【9月更文挑战第11天】在编程世界中,进程间通信(IPC)如同一座无形的桥梁,连接不同进程的信息孤岛,使应用无界而广阔。Python凭借其丰富的IPC机制,让开发者轻松实现进程间的无缝交流。本文将揭开Python IPC的神秘面纱,介绍几种关键的IPC技术:管道提供简单的单向数据传输,适合父子进程间通信;队列则是线程和进程安全的数据共享结构,支持多进程访问;共享内存允许快速读写大量数据,需配合锁机制确保一致性;套接字则能实现跨网络的通信,构建分布式系统。掌握这些技术,你的应用将不再受限于单个进程,实现更强大的功能。
44 5
|
22天前
|
消息中间件 Kafka 数据安全/隐私保护
Python IPC实战指南:构建高效稳定的进程间通信桥梁
【9月更文挑战第11天】在软件开发中,随着应用复杂度的提升,进程间通信(IPC)成为构建高效系统的关键。本文通过一个分布式日志处理系统的案例,介绍如何使用Python和套接字实现可靠的IPC。案例涉及定义通信协议、实现日志发送与接收,并提供示例代码。通过本教程,你将学会构建高效的IPC桥梁,并了解如何根据需求选择合适的IPC机制,确保系统的稳定性和安全性。
36 5
|
24天前
|
消息中间件 网络协议 Python
工具人逆袭!掌握Python IPC,让你的进程从此告别单打独斗
【9月更文挑战第9天】你是否曾遇到多个Python程序像孤岛般无法通信,导致数据孤立、任务难协同的问题?掌握进程间通信(IPC)技术,可助你打破这一僵局。IPC是不同进程间传递数据或信号的机制,在Python中常用的方法有管道、消息队列、共享内存及套接字等。其中,管道适用于父子或兄弟进程间简单数据传递;套接字则不仅限于本地,还能在网络间实现复杂的数据交换。通过学习IPC,你将能设计更健壮灵活的系统架构,成为真正的编程高手。
20 3
|
25天前
|
安全 开发者 Python
揭秘Python IPC:进程间的秘密对话,让你的系统编程更上一层楼
【9月更文挑战第8天】在系统编程中,进程间通信(IPC)是实现多进程协作的关键技术。IPC机制如管道、队列、共享内存和套接字,使进程能在独立内存空间中共享信息,提升系统并发性和灵活性。Python提供了丰富的IPC工具,如`multiprocessing.Pipe()`和`multiprocessing.Queue()`,简化了进程间通信的实现。本文将从理论到实践,详细介绍各种IPC机制的特点和应用场景,帮助开发者构建高效、可靠的多进程应用。掌握Python IPC,让系统编程更加得心应手。
22 4
|
25天前
|
消息中间件 数据库 Python
深度剖析!Python IPC的奥秘,带你走进进程间通信的微观世界
【9月更文挑战第8天】在编程世界中,进程间通信(IPC)是连接不同程序或进程的关键技术,使数据在独立进程间自由流动,构建复杂软件系统。本文将深入探讨Python中的IPC机制,包括管道、消息队列、套接字等,并通过具体示例展示如何使用Socket实现网络IPC。Python的`multiprocessing`模块还提供了队列、管道和共享内存等多种高效IPC方式。通过本文,你将全面了解Python IPC的核心概念与应用技巧,助力开发高效协同的软件系统。
39 2
|
3天前
|
数据采集 Linux 调度
Python之多线程与多进程
Python之多线程与多进程
10 0
下一篇
无影云桌面