管道,信号量,进程池

管道:

  conn1,conn2 = Pipe()

  conn1.recv()  # recv() 不需要加内容长度(整数)

  conn1.send()  # send() 不需要编码

  数据接收一次就没有了

def chi(n):
    print("我是子进程")
    from_conn1 = n.recv()
    print(from_conn1)

if __name__ == '__main__':
    conn1,conn2 = Pipe()
    p = Process(target=chi,args=(conn2,))
    p.start()
    conn1.send("儿子,干哈呢?")
    print("父进程结束")

  

事件:

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

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

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

  e.is_set() 查看状态

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

信号量:

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

  只有这一种方式来锁

    s.acquire()

    需要锁住的代码

    s.release()

  

import time
from multiprocessing import Process,Semaphore

def func1(n,m):
    n.acquire()
    print(f"{m}号女技师为您服务")
    time.sleep(1)
    n.release()

if __name__ == '__main__':
    s = Semaphore(3)
    for i in range(10):
        p = Process(target=func1,args=(s,i+1,))
        p.start()

  

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

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

  测试多进程和进程池的效率对比:

import time
from multiprocessing import Process,Pool

def f1(m):
    for i in range(5):
        m += i

if __name__ == '__main__':
    # 进程池设置三个进程
    p1 = Pool(3)
    # 创建进程时得到时间戳
    p1_go_time = time.time()
    # 参数1放进程的逻辑,参数2放可迭代对象.map是异步提交任务,但自带close和join
    p1.map(f1,range(100))
    # 所有进程结束后得到一个时间戳
    p1_end_time = time.time()
    p1_time = p1_end_time - p1_go_time

    p2_lis = []
    # 创建进程时得到时间戳
    p2_go_time = time.time()
    for i in range(100):
        # 创建进程对象,把循环的内容当做参数,传给函数
        p2 = Process(target=f1,args=(i,))
        p2.start()
        # 把进程对象都添加到列表中,方便让对象都join.
        p2_lis.append(p2)

    for i in p2_lis:
        #把每个创建的进程对象都join,进程最慢的执行完之后,继续向下执行
        #假如不加join的话,就是for循环创建完所有进程之后,直接向后执行,而子进程并没有执行完.
        i.join()  
    # 所有多进程结束后得到一个时间戳
    p2_end_time = time.time()
    p2_time = p2_end_time - p2_go_time

    print("进程池耗时:",p1_time)
    print("多进程耗时:", p2_time)

  

  

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

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

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

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

回调函数:

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

猜你喜欢

转载自www.cnblogs.com/gyc-tzx/p/10251462.html