随笔 - 105  文章 - 0  评论 - 0  阅读 - 40744

进程

一、进程的初步使用,方法和线程一样,只是类名不同而已,例子如下:

复制代码
from multiprocessing import Process
import time


def run(name):
    time.sleep(2)
    print('Hello, %s' % name)


if __name__ == '__main__':
    for i in range(10):
        p = Process(target=run, args=('Bob %s' % i,))
        p.start()
进程启动
复制代码

进程中又启动线程

复制代码
from multiprocessing import Process
import time
import threading


def thread_run():
    print(threading.get_ident())  # 获取线程ID


def run(name):
    time.sleep(2)
    print('Hello, %s' % name)
    t = threading.Thread(target=thread_run)
    t.start()


if __name__ == '__main__':
    for i in range(10):
        p = Process(target=run, args=('Bob %s' % i,))
        p.start()
进程中包含线程
复制代码

 获取进程ID,并从以下例子中得出,所有的子进程都有你进程

复制代码
import os
from multiprocessing import Process


def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process id:', os.getppid())
    print('process id:', os.getpid())
    print('\n\n')


def f(name):
    info('\033[31;1mcalled from child process function f\033[0m')
    print('Hello', name)


if __name__ == '__main__':
    info('\033[1;32mmain process line\033[0m')
    p = Process(target=f, args=('bob',))
    p.start()
获取进程ID
复制代码

 

二、进程间通讯

1、进程队列(Queue)

(1)、其实进程队列并不能实现数据的共享,只是进程把数据首先经过序列化发给第三方,然后第三方把数据发送给另外一个进程,反序列化,这其实是数据的传递。例子:

复制代码
from multiprocessing import Process, Queue
q = Queue()


def f(q):  # 注意:进程之间使用队列,必须要使用队列作为参数传递
    q.put([42, None, 'Hello'])


if __name__ == '__main__':
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())
    p.join()
Queue实现进程间通讯
复制代码

注意:父进程启动子进程时,需要把队列作为参数传递

2、管道(Pipe)

(1)、管道的实现和socket的接发数据差不多,也有recv、send方法,使用步骤如下:

A、定义实例,会返回两个对象,parent_conn,child_conn = Pipe()

B、启动进程时,把child_conn此对象传递给子进程

例子如下:

复制代码
from multiprocessing import Process, Pipe


def f(conn):
    conn.send('Hello from child1')
    conn.send('Hello from child2')
    print(conn.recv())
    conn.close()


if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print(parent_conn.recv())
    print(parent_conn.recv())
    parent_conn.send('我很好')
    parent_conn.close()
管道
复制代码

 3、Manager

(1)、Manager可实现多进程间共享

(2)、步骤

A、实例化,manager = Manager()

B、初始化变量,如d = manager.dict()

C、把初始化的变量传递给函数, P = Process(target=func, args=(d,l))

例子:

复制代码
from multiprocessing import Process, Manager
import os


def fun(d, l):
    d[os.getpid()] = os.getpid()
    l.append(os.getpid())
    print(d)
    print(l)


if __name__ == '__main__':
    manager = Manager()
    d = manager.dict()
    l = manager.list(range(5))
    p_list = []
    for i in range(10):
        p = Process(target=fun, args=(d, l))
        p_list.append(p)
        p.start()
    for p in p_list:
        p.join()
    print(d)
    print(l)
Manager
复制代码

 

三、进程锁

1、存在的意义:进程之间数据是独立的,为什么还要进程锁?因为进程之间共享了一些资源,如屏幕。。。

2、用法:

(1)、实例化

(2)、把锁作为参数在实例化进程时传递

(3)、lock.acquire()....lock.release()

3、例子:

复制代码
from multiprocessing import Process, Lock


def hello(l, name):
    l.acquire()
    print('hello ',name)
    l.release()


if __name__ == '__main__':
    lock = Lock()
    for i in range(10):
        p = Process(target=hello, args=(lock, i))
        p.start()
Lock
复制代码

 

四、进程池

1、作用:和线程的信号量一样,只允许N个进程同时执行。可在实例化时定义。

2、用法:

(1)、实例化 pool = Pool(5)

(2)、pool.apply(func=func_name,args=())  串行

            pool.apply_async(func=func_name,args=()) 并行

(3)、pool.close()

            pool.join()  必须要先close再join

3、例子:

复制代码
from multiprocessing import Pool
import time
import os


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


if __name__ == '__main__':
    pool = Pool(5)
    for i in range(10):
        # pool.apply(func=run, args=(i,))  # 串行
        pool.apply_async(func=run, args=(i,))  # 并行
    pool.close()
    pool.join()  # 必须要先close再join!!
进程池
复制代码

4、进程池中的回调

(1)、可在pool.apply_async中添加参数callback,则在func参数执行完就执行callback,并且会把func返回的结果传递给callback

例子:

复制代码
from multiprocessing import Pool
import time
import os


def run(i):
    time.sleep(2)
    print('in the process', os.getpid())
    return i + 50


def bar(arg):
    print('-->exec done:', arg)
    print('process id:', os.getpid())


if __name__ == '__main__':
    print('main process id', os.getpid())
    pool = Pool(3)
    for i in range(10):
        # pool.apply(func=run, args=(i,))  # 串行
        pool.apply_async(func=run, args=(i,), callback=bar)
    pool.close()
    pool.join()  # 必须要先close再join!!
回调
复制代码

 

posted on   Treelight  阅读(145)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示