Python 多进程

复制代码
# 一些进程相关的函数
import multiprocessing
import threading
import os

# 设置创建进程的模式:
# fork          创建进程的时候会拷贝整个start启动进程之前的所有资源,也可以通过参数去传递。它是unix下的
# spawn         该模式是windows的固定模式。创建进程的时候资源不会拷贝,但是你可以通过参数去传递,参数如果是对象的话,新的进程和主进程的对象id不一样。这种模式python在创建进程的时候会将进程代码编译一次然后以进程的方式运行。windows和unix都行
# forkserver    该模式只适用部分unix系统。它也不会拷贝资源。他是将一个进程做成一个模板。
def task(fb):
    print(fb)
multiprocessing.set_start_method('fork') # 设置创建进程的模式:
p1 = multiprocessing.Process(target=task, args=('test'))
p1.start()          # 启动进程
p1.join()           # 等待进程结束
p1.daemon = False   # 进程是否后台运行,也就是需要不要主进程等待,就相当于主进程结束前会检查一下子进程是否结束,没结束主进程就会等待。默认是True。需要在start前设置
p1.name = 'pname'   # 设置进程名字,需要在start前设置
multiprocessing.current_process().name # 获取当前进程的名字
os.getpid()         # 获取进程id
os.getppid()        # 获取父进程it
threading.enumerate() # 返回进程中所有的线程(id,name之类)
multiprocessing.cpu_count() # 获取cpu个数。创建合理的进程数量可以根据这个值来决定。

# 以类的方式实现进程
class MyProcess(multiprocessing.Process):
    def run(self):
        print('执行此进程', self._args)
if __name__ == '__main__':
    multiprocessing.set_start_method('fork')
    p = MyProcess(args=('xxx',))
    p.start()
    print('...')
    
# 进程之间的数据共享
from multiprocessing import Process, Value, Array, Manager
# Value :  不好的地方就是用的时候比较麻烦
# 'c' ctypes.c_char, 'u':ctypes.c_wchar
# 'b' ctypes.c_type, 'B':ctypes.c_ubyte
# 'h' ctypes.c_short, 'U':ctypes.c_ushort
# 'i' ctypes.c_int, 'I':ctypes.c_uint
# 'l' ctypes.c_long, 'L':ctypes.c_ulong
# 'f' ctypes.c_float, 'F':ctypes.c_double
def func(m, m1, m2):
    m.value = 111
    m1.value = 'a'.encode('utf-8')
    m2.value = ''
def func1(arr):
    arr[0] = 666  # zhe
def func2(d, l):
    d[1] = '1'   # 对字典操作
    d['2'] = 2
    l.append(666)# 对列表操作

if __name__ == '__main__':
    num = Value('i', 666)  # 第一个参数是类型,第二个参数是值
    v1 = Value('c')
    v2 = Value('u')

    p = Process(target=func, args=(num, v1, v2))
    p.start()
    p.join()

    arr = Array('i', [11,22,33,44]) # 相当于c语言中的数组,长度不可改变,值类型不可更变
    p1 = Process(target=func1, args=(arr, ))
    p1.start()

    with Manager() as manage:
        d = manage.dict()
        l = manage.list()
        p2 = Process(target=func2, args=(d, l))
        p2.start()
# 进程之间的消息队列和管道
from multiprocessing import Process, Queue, Pipe
import time
def task(que):
    for i in range(10):
        que.put(i)  # 往消息队里里边推入值
def func_pipe(comm)        :
    time.sleep(1)
    comm.send([11,2,33])
    data = comm.recv() # 阻塞
if __name__ == '__main__':
    queue = Queue() # 创建消息队列
    p = Process(target=task, args=(queue))
    p.start()
    p.join()
    queue.get() # 从消息队列里边拿值

    parent_comm, child_comm = Pipe()

    p1 = Process(target=func_pipe, args=(child_comm,))
    p1.start()
    # p1.join()
    info = parent_comm.recv() # 阻塞
    parent_comm.send(666)

# 进程锁,和线程锁一样的使用
from multiprocessing import Process, RLock, Lock
# 进程池,和线程池差不多
from multiprocessing import Manager
from concurrent.futures import ProcessPoolExecutor
from multiprocessing import Process
def task(num):
    print('执行', num)
    time.sleep(1)
    return num
def done(res):
    print(multiprocessing.current_process())  # 验证该任务是由主进程执行的
    time.sleep(1)
    print(res.result())
    time.sleep(1)
if __name__ = '__main__':
    pool = ProcessPoolExecutor(4)   # 创建进程池
    lock = Manager.RLock()# 进程池中你要用锁的话就得用这个
    for i in range(50):
        fur = pool.submit(task, i)    # 往进程池中丢任务
        fur.add_done_callback(done)    # 将执行结果给done去执行
    print(multiprocessing.current_process())
    pool.shutdown(True) # 等待所有进程执行完
复制代码

 

posted @   看一百次夜空里的深蓝  阅读(157)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示