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

####################总结########################

管道:是进程间通信的第二种方式,但是不推荐使用,因为管道会导致数据不安全的情况出现

事件:当我运行主进程的时候 需要子执行某个进程后 需要的返回值时 可以使用

信号量:互斥锁同时只允许一个线程更改数据,而信号量Semaphore是同时允许一定数量的线程更改数据 。

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

进程池: 

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

  进程池:定义一个池子,池中进程的数量是固定的,那么同一时间有固定数量的进程在运行。

     这样不会增加操作系统的调度难度,还节省了开闭进程的时间,也一定程度上能够实现并发效果

管道

###管道
from multiprocessing import Process,Pipe

def f1(conn):
    zhu=conn.recv()
    print(‘我是子进程‘)
    print(‘来自主进程消息‘,zhu)
if __name__ == ‘__main__‘:
    conn1,conn2=Pipe()
    p1=Process(target=f1,args=(conn2,))
    p1.start()
    conn1.send(‘我是conn1‘)
    print(‘我是主进程‘)
#######################
我是主进程
我是子进程
来自主进程消息 我是conn1

事件

from multiprocessing import Process,Event
e=Event()
print(‘e的状态是‘,e.is_set())
print(‘进程运行到这里了‘)
e.set()#将e的状态改为True
print(‘e的状态是‘,e.is_set())

e.clear()#将e的状态改为False
e.wait()#e这个事件对象如果值为False,就在我加wait的地方等待
print(‘进程过了wait‘)
##################
e的状态是 False
进程运行到这里了
e的状态是 True

信号量

import time
import 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()
###############
6男嘉宾到了
4男嘉宾到了
7男嘉宾到了
3男嘉宾到了
#前面的人出去了,出去一个就往后上加
2男嘉宾到了
1男嘉宾到了
0男嘉宾到了
5男嘉宾到了
9男嘉宾到了
8男嘉宾到了

进程池 map

import time
from multiprocessing import Pool,Process
#计算下开多进程和进程池的执行效率
def func(n):
    for i in range(5):
        n = n + i
        # print(n)
if __name__ == ‘__main__‘:
    #进程池模式时间统计
    pool_s_time = time.time()
    pool = Pool(4)    #创建含有4个进程的进程池   ****一般约定俗成的是进程池中的进程数量为CPU的数量,工作中要看具体情况来考量
    pool.map(func,range(100))    #参数数据必须是可迭代的,异步提交任务,自带join功能
                                 #注意,map目前只限于接收一个可迭代的数据类型参数,
    #多进程模式
    pool_end_time = time.time()
    pool_dif_time = pool_end_time - pool_s_time
#############进程时间统计#####################################
    # 统计100个进程,来执行100个任务的执行时间
    p_s_time = time.time()
    p_lst= [] #因为这个是异步的,我子进程执行他自己的,如果直接在for循环join会每个进程等待
    #所以要放到进程直接 内存中 然后在join
    for i in range(100):
        p = Process(target= func,args = (i,))
        p.start()
        p_lst.append(p)
    [p.join() for p in p_lst]
    p_e_time = time.time()
    p_dif_time = p_e_time - p_s_time

    print("进程池的执行时间",pool_dif_time)   #0.176239013671875      进程池 的效率高
    print("创建进程的执行时间",p_dif_time)    #7.825609922409058

进程池同步 把进程池 变串行执行的方式

import time
from multiprocessing import Process,Pool
def f1(n):
    time.sleep(1)
    # print(n)
    return n*n
if __name__ == ‘__main__‘:
    pool = Pool(4)
    for i in range(10):
        print(‘xxxxxx‘)
        res = pool.apply(f1,args=(i,))
        print(res)
############
xxxxxx
0
xxxxxx
1
xxxxxx
4
xxxxxx
9
xxxxxx
16

进程池 异步执行

import time
from multiprocessing import Pool

def f1(i):
    time.sleep(1)
    # print(i)
    return i
if __name__ == ‘__main__‘:
    p=Pool(4)
    res_lst=[]#循环
    for i in range(10):
        # print(‘xxxx‘)
        res=p.apply_async(f1,args=(i,))
        # print(res)#10个空结果对象
        res_lst.append(res)#把结果值打印大内存中
    #主进程运行结果,进程池里面的任务全部停止,不会等待进程池里面的任务
    # p.close()#锁住进程池,意思就是不让其他的程序再往这个进程池里面提交任务了
    # p.join()#它的作用是等到进程池的任务全部执行完,然后结束主进程
    #默认会 4个一打印  有了这2个参数后就会 一次性获取出来
    for r in res_lst:
        print(r.get())
    print(‘等待所有任务执行完‘)#########################################

D:\python_work_s18\venv\Scripts\python.exe D:/python_work_s18/day31/1111.py
0
1
2
3

--
4
5
6
7

---
8
9
等待所有任务执行完

回调函数:

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

import os
from multiprocessing import Pool,Process
def f1(n):
    print(‘进程池里面的进程id‘,os.getpid())
    print(‘>>>>‘,n)
    return n*n
def call_back_func(asdf):
    print(‘>>>>>>>‘,os.getpid())
    print(‘回调函数中的结果:‘, asdf)
if __name__ == ‘__main__‘:
    pool=Pool(4)
    res = pool.apply_async(f1,args=(5,),callback=call_back_func)
    pool.close()
    pool.join()
    print(‘主进程id‘,os.getpid())
################################
进程池里面的进程id 7872
>>>> 5
>>>>>>> 8640
回调函数中的结果: 25
主进程id 8640

原文地址:https://www.cnblogs.com/zaizai1573/p/10253218.html

时间: 2024-10-10 00:38:15

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

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() #创建一个管

协程,事件,队列,同步,异步,回调函数

协程 什么是协成?单个线程并发的处理多个任务,程序控制协成的切换+保持状态,协成的切换速度非常快,蒙蔽了操作系统的眼睛,让操作系统认为CPU一直在运行 进程或线程都是由操作系统控制CPU来回切换,遇到阻塞就切换执行其他任务,协成是程序控制的,霸占CPU执行任务,会在操作系统控制CPU之前来回切换,操作系统就认为CPU一直在运作 协程的优点: 1.开销小 2.运行速度快 3.协程会长期霸占CPU只执行我程序里的所有任务 协程的缺点: 1.协程属于微并发,处理任务不易过多 2.协程的本质是单线程,无

同步异步 + 回调函数

重点记忆 异步回调函数 如果进程池+回调: 回调函数由主进程去执行. 如果线程池+回调: 回到函数由空闲的线程去执行.(比如有4个线程,10个任务,第一轮完成4个任务,交由主线程处理结果,第二轮同样如此,但是第三轮将会空闲出2个子进程,则这2个子进程将会和主进程一同处理结果,以此类推,当所有的任务完成时,所有的子进程和主进程一起处理结果,增加效率) 回调函数不管有没有返回数据,返回值都是None,回调函数内部加函数名是调用此函数,obj隐形传参 1.概念 1. 从执行的角度 阻塞: 程序运行时,

python GIL锁、进程池与线程池、同步异步

一.GIL全局解释器锁 全局解释器锁 在CPython中,全局解释器锁(GIL)是一个互斥锁,它可以防止多个本机线程同时执行Python代码.之所以需要这个锁,主要是因为CPython的内存管理不是线程安全的.(然而,自从GIL存在以来,其他特性已经逐渐依赖于它所执行的保证) 什么是GIL 全局解释器锁, 施加在解释器上的互斥锁 为什么需要GIL 由于CPython的内存管理时非线程安全,于是CPython就给解释器加上锁, 解决了安全问题. GIL的加锁与解锁时机 加锁的时机: 在调用解释器时

python37 1.GIL--全局解释器锁 2.GIL带来的问题 3.为什么需要GIL 4.GIL的加锁解锁时机 5.关于GIL的性能的讨论 6.线程常用方法 7.GIL锁与自定义锁的区别 8.进程池与线程池 9.同步异步 10.异步调用

复习1.JoinableQueue--可以被join的队列2.多线程3线程的使用方法与进程一模一样3.1守护线程3.2线程安全问题3.3解决方案3.3.1互斥锁mutex3.3.2递归锁Rlock3.3.3信号量semaphore3.3.4死锁问题 详解:1.JoinableQueue--可以被join的队列 1.1join是等待任务结束 队列怎么叫结束 调用task_done一次则表示有一个数据被处理完成了,当task_done次数等于put的次数就意味着任务处理完成了 1.2这就是join的

30分钟读懂进程线程、同步异步、阻塞非阻塞、并发并行

基本概念 1 进程和线程 进程(Process): 是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源.一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程.线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码.进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的.进程可以理解为一个程序的基本边界.是

2015/01/23 – 不要对异步回调函数进行同步调用

绝对不能对异步回调函数(即使在数据已经就绪)进行同步调用. 如果对异步回调函数进行同步调用的话,处理顺序可能会与预期不符,可能带来意料之外的后果. 对异步回调函数进行同步调用,还可能导致栈溢出或异常处理错乱等问题. 如果想在将来某时刻调用异步回调函数的话,可以使用 setTimeout 等异步API. function onReady(fn) { var readyState = document.readyState; if (readyState == 'interactive' || re

js同步-异步-回调

出处:https://blog.csdn.net/u010297791/article/details/71158212(1)上面主要讲了同步和回调执行顺序的问题,接着我就举一个包含同步.异步.回调的例子. let a = new Promise(//声明了一个Promise回调函数,能够使用then function(resolve, reject) { console.log(1) setTimeout(() => console.log(2), 0) console.log(3) cons

python 之 并发编程(进程池与线程池、同步异步阻塞非阻塞、线程queue)

9.11 进程池与线程池 池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务 池子内什么时候装进程:并发的任务属于计算密集型 池子内什么时候装线程:并发的任务属于IO密集型 进程池: from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor import time,os,random ? def task(x): print('%s 接客' %os.getpid()) time.