047 Python语法之多进程

本文介绍了Python中的多进程知识,包括进程的概念、进程与线程的区别、CPU密集型任务适合多进程、IO密集型任务适合多线程。详细讲解了如何创建进程、使用进程锁及多种进程间通信方式如Pipe、Queue、Value、Array和dict、list。还探讨了进程池和分布式进程的Master-Worker模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进程相关知识

  1. 进程不能共享数据
  2. 进程会复制一份新的数据,数据具有新的控件存储

进程的概念

  1. 进程就是一个程序对各种资源的集合
  2. 多线程在根本上并不是真正意义上的并发,而是多个线程进行切换
  3. 多进程在本质上才是并发的
  4. 一个线程里面至少有一个线程
  5. 进程的第一个线程就是主线程
  6. 两个线程之间可以直接通信

进程和线程的区别

  1. 线程与进程没有可比性
  2. 创建一个线程比创建一个进程快,进程需要资源多
  3. 进程内部还是需要线程进行执行的
  4. 线程之间可以共享数据
  5. 进程之间是独立的

CPU密集型(多进程)

  1. 计算,深度学习训练
  2. 科学计算
  3. 内存版检索开房

IO密集型(多线程)

  1. 网络下载
  2. 网络等待
  3. 文件操作

创建一个进程

import multiprocessing

def gogogo():
    time.sleep(10)
    mylist = [x for x in range(10000000)]
    print(hello)
    print(os.getppid()) # 获取父进程编号
    print(os.getpid())  # 获取当前进程编号
    print(id(mylist))

if __name__=="__main__":
    gogogo()
    p = multiprocessing.Process(target=gogogo,args=())
    p.start()
    p.join()    # 阻塞主进程

进程的一些方法

  1. os.getppid() # 获取父进程编号
  2. os.getpid() # 获取进程编号

进程锁

lock=multiprocessing.RLock()#创建一个锁

# Author:Luo
import time
import multiprocessing
import os


def TestGo(lock, title):
    print(title)  # 上半段并发
    with  lock:  # 下半段,lock多个进程之间共享
        time.sleep(2)
        print(__name__)  # 执行模块的名称
        print("father pid", os.getppid())  # 获取父进程编号
        print("self  pid", os.getpid())  # 获取进程编号


if __name__ == "__main__":
    lock = multiprocessing.RLock()  # 创建一个锁
    TestGo(lock, "王毅")
    namelist = ["房久博", "王雪飞", "李培伦", "王涛"]
    plist = []  # 进程列表
    for name in namelist:
        p = multiprocessing.Process(target=TestGo, args=(lock, name))
        p.start()
        plist.append(p)
    for p in plist:
        p.join()

进程间通信Pipe

import multiprocessing
import os


def go(conn):  # 传递一个管道
    print("子进程开始")
    list1 = conn.recv()     # 同步运行,没有数据发送会阻塞
    print(os.getppid(), os.getpid(), list1)
    conn.send(["1234"])
    print("子进程结束")


if __name__ == "__main__":
    conn_a, conn_b = multiprocessing.Pipe()
    multiprocessing.Process(target=go, args=(conn_a,)).start()
    conn_b.send(["abcd"])
    list2 = conn_b.recv()
    print(os.getppid(), os.getpid(), list2)

进程间共享数据Queue

import multiprocessing
import time
import os


def go(myQue):
    print(myQue.get())
    myQue.put("123")


if __name__ == "__main__":
    myQue = multiprocessing.Queue()
    myQue.put("abc")
    myQue.put("abcd")
    multiprocessing.Process(target=go, args=(myQue,)).start()
    print(myQue.get())

进程间共享数据Value

import multiprocessing

def  func(num):
    num.value=12

if  __name__=="__main__":
    num=multiprocessing.Value("d",10)# d整数  多个进程共享
    print(num.value)
    p=multiprocessing.Process(target=func,args=(num,))
    p.start()
    p.join()
    print(num.value)

进程间共享数据Array

import multiprocessing

def  func(num):
    num[2]=9999

if  __name__=="__main__":
    array=multiprocessing.Array("i",[1,2,3,4,5]) # i整数,不能增加元素
    print(array[:])

    p=multiprocessing.Process(target=func,args=(array,))
    p.start()
    p.join()
    print(array[:])

进程间共享数据dict

进程间共享数据list

import multiprocessing

def func(mydict, mylist):
    mylist.append(10)
    mylist.append(11)
    mylist.append(12)

    mydict["王毅"]=175


if  __name__=="__main__":
    mydict=multiprocessing.Manager().dict()
    mylist=multiprocessing.Manager().list(range(5))
    mydict["王雪飞"]=180
    print(mylist)
    print(mydict)

    p=multiprocessing.Process(target=func,args=(mydict, mylist))
    p.start()
    p.join()
    print(mylist)
    print(mydict)

进程池

import time
import  multiprocessing
import  os

def  TestGo(title):
    print(title)  #上半段并发

    time.sleep(5)
    print(__name__) #执行模块的名称
    print("father pid", os.getppid())  # 获取父进程编号
    print("self  pid", os.getpid())  # 获取进程编号

if __name__=="__main__":
    namelist=["房久博","王雪飞","李培伦","王涛"]
    pool=multiprocessing.Pool(1)#限制并发进程数量
    for  name in namelist:
        pool.apply_async(TestGo,args=(name,))
        #pool.apply()#同步
    pool.close()#结束插入进程,开始执行
    pool.join()#等待
    print("完成")

分布式进程

Master
import  multiprocessing
import multiprocessing.managers
import  random,time,queue

task_queue=queue.Queue() #任务队列
result_queue=queue.Queue()#结果队列
def  return_task():   #返回任务队列
    return  task_queue
def  return_result(): #返回结果队列
    return  result_queue
class  QueueManger(multiprocessing.managers.BaseManager):#继承,实现进程数据共享
    pass

if  __name__=="__main__":
    multiprocessing.freeze_support() #初始化,开启分布式支持
    QueueManger.register("get_task",callable=return_task)#注册共享,
    QueueManger.register("get_result", callable=return_result)
    #创建一个管理者,设置ip,端口,密码
    manager=QueueManger(address=('10.0.147.185',8848),authkey=b'abc')
    manager.start() #开启服务器管理
    task,result=manager.get_task(),manager.get_result() #task任务,result结果
    for  i  in range(5):
        print("task加入数据",i)
        task.put(i)
    print("尝试开始取出结果")
    for  i  in range(5):
        r=result.get(timeout=50)
        print("抓到数据",r)
    manager.shutdown()#关闭服务器
    print("完成")
Worker
import  multiprocessing
import multiprocessing.managers
import  random,time,queue

class  QueueManger(multiprocessing.managers.BaseManager):#继承,实现进程数据共享
    pass

if  __name__=="__main__":
    QueueManger.register("get_task")#注册共享,
    QueueManger.register("get_result")
    severip="10.0.147.185"
    print("开始链接服务器")
    manager=QueueManger(address=(severip,8848),authkey=b'abc')
    manager.connect()#链接
    print("服务器连接成功")

    task=manager.get_task()
    result=manager.get_result()#抓取任务队列,结果队列
    for  i  in range(5):
        try:
            t=task.get(timeout=10)
            print("取出数据",t)
            result.put(10+t)#加工数据返回到结果队列
        except :
            print("队伍为空其他异常")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆豆orz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值