python并发编程(管道,事件,信号量,进程池)

管道

Conn1,conn2 = Pipe()

Conn1.recv()

Conn1.send()

数据接收一次就没有了

from multiprocessing import Process,Pipe

def f1(conn):

    from_zhujincheng = conn.recv()
    print(‘子进程‘)
    print(‘来自主进程的消息:‘,from_zhujincheng)

if __name__ == ‘__main__‘:
    conn1,conn2 = Pipe()  #创建一个管道对象,全双工,返回管道的两端,但是一端发送的消息,只能另外一端接收,自己这一端是不能接收的
    p1 = Process(target=f1,args=(conn2,))
    p1.start()

    conn1.send(‘出来吧‘)
    print(‘主进程‘)

事件

E = Event()  #初识状态是false

E.wait()  当事件对象e的状态为false的时候,在wait的地方会阻塞程序,当对象状态为true的时候,直接在这个wait地方继续往下执行

E.set()  将事件对象的状态改为true,

E.is_set() 查看状态

E.clear()  将事件对象的状态改为false

from multiprocessing import Process,Event

e = Event()  #创建事件对象,这个对象的初识状态为False
print(‘e的状态是:‘,e.is_set())  #  False

print(‘进程运行到这里了‘)
e.set()  #将e的状态改为True
print(‘e的状态是:‘,e.is_set())  #  True

e.clear()  #将e的状态改为False

e.wait()  #e这个事件对象如果值为False,就在我加wait的地方等待

print(‘进程过了wait‘)

信号量

S = semphore(数字),内部维护了一个计数器,acquire-1,release+1,为0的时候,其他的进程都要在acquire之前等待

S.acquire()

需要锁住的代码

S.release()

import time,random
from multiprocessing import Process,Semaphore

def f1(i,s):
    s.acquire()
    print(‘%s男嘉宾到了‘%i)
    time.sleep(random.randint(1,3))
    s.release()

if __name__ == ‘__main__‘:
    s = Semaphore(4)  #计数器4,acquire一次减一,为0 ,其他人等待,release加1
    for i in range(10):
        p = Process(target=f1,args=(i,s))
        p.start()

进程池

进程的创建和销毁是很有消耗的,影响代码执行效率

在有进程池的代码中,主进程运行结束,进程池里面的任务全部停止,不会等待进程池里面的任务

pl = Pool(数字)   这个数字一般是电脑的cpu数

pl的方法:

  Map:异步提交任务,并且传参需要可迭代类型的数据,自带close和join功能

import time
from multiprocessing import Process,Pool

#对比多进程和进程池的效率
def f1(n):
    for i in range(5):
        n = n + i

if __name__ == ‘__main__‘:

    #统计进程池执行100个任务的时间
    s_time = time.time()
    pool = Pool(4)
    pool.map(f1,range(100))
    e_time = time.time()
    dif_time = e_time - s_time

    #统计100个进程,来执行100个任务的执行时间
    p_s_t = time.time() #多进程起始时间
    p_list = []
    for i in range(100):
        p = Process(target=f1,args=(i,))
        p.start()
        p_list.append(p)
    [pp.join() for pp in p_list]
    p_e_t = time.time()
    p_dif_t = p_e_t - p_s_t
    print(‘进程池的时间:‘,dif_time)
    print(‘多进程的执行时间:‘,p_dif_t)
    # 结果:  进程池的时间: 0.40102291107177734    多进程的执行时间: 9.247529029846191
    # 可以看出进程池运行效率远远大于创建多进程

  Close : 锁住进程池,防止有其他的新的任务在提交给进程池

  Join : 等待着进程池将自己里面的任务都执行完

  Res = Apply(f1,args=(i,))  #同步执行任务,必须等任务执行结束才能给进程池提交下一个任务,可以直接拿到返回结果res

import time
from multiprocessing import Process,Pool

def f1(n):
    time.sleep(1)
    return n*n

if __name__ == ‘__main__‘:

    pool = Pool(4)
    for i in range(10):
        res = pool.apply(f1,args=(i,))
        print(res)

  Res_obj = Apply_async(f1,args=(i,))  #异步提交任务,可以直接拿到结果对象,从结果对象里面拿结果,要用get方法,get方法会阻塞程序,没有拿到结果会一直等待

import time
from multiprocessing import Process,Pool

def f1(n):
    time.sleep(0.5)
    return n*n

if __name__ == ‘__main__‘:

    pool = Pool(4)

    res_list = []
    for i in range(10):
        res = pool.apply_async(f1,args=(i,)) # 不能直接打印返回值,因为直接返回结果对象,进程还没执行完,结果对象里没有数据
        res_list.append(res)

    pool.close()
    pool.join()

    #打印结果,异步提交之后的结果对象
    for i in res_list:
        print(i.get())

回调函数:

Apply_async(f1,args=(i,),callback=function)  #将前面f1这个任务的返回结果作为参数传给callback指定的那个function函数

import os
from multiprocessing import Pool,Process

def f1(n):
    print(‘传入的函数‘,n)
    return n*n

def call_back_func(asdf):
    print(‘回调函数‘,asdf)

if __name__ == ‘__main__‘:
    pool = Pool(4)
    res = pool.apply_async(f1,args=(5,),callback=call_back_func)
    pool.close()
    pool.join()

原文地址:https://www.cnblogs.com/fu-1111/p/10252404.html

时间: 2024-11-10 00:39:06

python并发编程(管道,事件,信号量,进程池)的相关文章

python 管道 事件 信号量 进程池(map/同步/异步)回调函数

####################总结######################## 管道:是进程间通信的第二种方式,但是不推荐使用,因为管道会导致数据不安全的情况出现 事件:当我运行主进程的时候 需要子执行某个进程后 需要的返回值时 可以使用 信号量:互斥锁同时只允许一个线程更改数据,而信号量Semaphore是同时允许一定数量的线程更改数据 . 内部维护了一个计数器,acquire-1,release+1,为0的时候,其他的进程都要在acquire之前等待 进程池:  进程的创建和销

Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信

目录 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 2.僵尸进程和孤儿进程 2.1僵尸进程 2.2孤儿进程 2.3僵尸进程如何解决? 3.互斥锁,锁 3.1互斥锁的应用 3.2Lock与join的区别 4.进程之间的通信 进程在内存级别是隔离的 4.1基于文件通信 (抢票系统) 4.2基于队列通信 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 1.创建进程的两种方式: 函数, 类. 2.pid: os.getpid() os.get

python并发编程基础之守护进程、队列、锁

并发编程2 1.守护进程 什么是守护进程? 表示进程A守护进程B,当被守护进程B结束后,进程A也就结束. from multiprocessing import Process import time ? def task(): print('妃子的一生') time.sleep(15) print('妃子死了') ? if __name__ == '__main__': fz = Process(target=task) fz.daemon = True #将子进程作为主进程的守护进程.必须在

12 并发编程-(线程)-线程queue&进程池与线程池

queue 英 /kju?/ 美 /kju/ 队列 1.class queue.Queue(maxsize=0) #队列:先进先出 import queue q=queue.Queue() q.put('first') q.put('second') q.put('third') print(q.get()) print(q.get()) print(q.get()) ''' 结果(先进先出): first second third ''' 2.class queue.LifoQueue(max

Python并发编程:多线程-信号量,Event,定时器

一 信号量 信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行,如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所所有多个坑位,这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小 from threading import Thread, Semaphore import threading import time def func(): sm.a

python并发编程02/多进程

目录 python并发编程02/多进程 1.进程创建的两种方式 1.1开启进程的第一种方式 1.2开启进程的第二种方式 1.3简单应用 2.进程pid 2.1命令行获取所有的进程的pid tasklist 2.2代码级别如何获取一个进程的pid 2.3获取父进程(主进程)的pid 3.验证进程之间的空间隔离 4.进程对象join方法 5.进程对象其他属性 6.守护进程 python并发编程02/多进程 1.进程创建的两种方式 1.1开启进程的第一种方式 from multiProcessing

Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池

目录 Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池 1.昨日回顾 2.死锁现象与递归锁 2.1死锁现象 2.2递归锁 3.信号量 4.GIL全局解释器锁 4.1背景 4.2为什么加锁 5.GIL与Lock锁的区别 6.验证计算密集型IO密集型的效率 6.1 IO密集型 6.2 计算密集型 7.多线程实现socket通信 7.1服务端 7.2客户端 8.进程池,线程池 Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池 1.昨日回顾 #生产者消

Python并发编程—进程池

进程池实现 1.必要性[1] 进程的创建和销毁过程消耗的资源较多[2] 当任务量众多,每个任务在很短时间内完成时,需要频繁的创建和销毁进程.此时对计算机压力较大[3] 进程池技术很好的解决了以上问题. 2.原理 创建一定数量的进程来处理事件,事件处理完进 程不退出而是继续处理其他事件,直到所有事件全都处理完毕统一销毁.增加进程的重复利用,降低资源消耗. 3.进程池实现 [1] 创建进程池对象,放入适当的进程 from multiprocessing import Pool Pool(proces

Python并发编程之进程2

引言 本篇介绍Python并发编程下的进程,先介绍进程的相关知识,然后对python中multiprocessing模块进行介绍(Process.Pipe.Queue以及 Lock). 进程(process) 在面向线程设计的系统(如当代多数操作系统.Linux 2.6及更新的版本)中,进程本身不是基本运行单位,而是线程的容器. 进程拥有自己独立的内存空间,所属线程可以访问进程的空间. 程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 例如,我们在PyCharm开发环境中写