1.管道(了解)
Pipe(): 在进程之间建立一条通道,并返回元组(conn1,conn2),其中conn1,conn2表示管道两端的连接对象,强调一点:必须在产生Process对象之前产生管道.
from multiprocessing import Process,Pipe
conn1,conn2 = Pipe()  结构
主要方法:
conn1.recv():接受conn2.send(obj)发送的对象.如果没有消息可接受, recv方法会一直阻塞.如果连接的另一端已经关闭,那么recv方法会跑输EOEError.
conn1.send(obj):通过连接发送对象.obj是与序列化兼容的任意对象
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('我是主进程')
2.信号量  Semaphore
互斥锁同时只允许一个线程更改熟路,而信号量时同事允许一定数量的线程更改数据
s=Semaphore() 内部维护了一个计数器,acquire -1,release +1,为0的时候,其他的进程都要在acquire之前等待
s.acquire()
需要锁住的代码
s.release()
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)
 
    for i in range(10):
        p = Process(target=f1,args=(i,s))
 
        p.start()
3.事件 Event
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())
 
print('进程运行到这里')
e.set() #将e的状态更改为True
print('e的状态是:',e.is_set())
 
e.clear() #将e的状态更改为False
e.wait()  #e这个事件对象如果值为False,就在我加wait的地方等待
print('进程过了wait')
 基于事件的进程通信:
import time
from multiprocessing import  Process,Event
 
def f1(e):
    time.sleep(2)
    n = 100
    print('子进程计算结果为',n)
    e.set()
 
if __name__ == '__main__':
    e = Event()
    p = Process(target=f1,args=(e,))
    p.start()
 
    print('主进程等待....')
    e.wait()
    print('结果已经写入文件,可以拿到值')
4.进程池(重点) Pool 池子
对比:多进程和多进程池的效率对比:进程的创建和销毁时很消耗的,影响代码执行效率
pool.map() 参数数据必须是可迭代的,异步提交任务,自带close和join功能
import time
from multiprocessing import Process,Pool
 
 
# def f1(n):
#     time.sleep(1)
#     print(n)
 
#对比多进程和进程池的效率
def f1(n):
    for i in range(5):
        n = n + i
if __name__ == '__main__':
    #统计进程池执行100个任务的时间
    s_time = time.time()
    pool = Pool(4)  #里面这个参数是指定进程池中有多少个进程用的,4表示4个进程,如果不传参数,默认开启的进程数一般是cpu的个数
    # pool.map(f1,[1,2])  #参数数据必须是可迭代的
    pool.map(f1,range(100))  #参数数据必须是可迭代的,异步提交任务,自带join功能
    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)
        # p.join()
    [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
进程池的同步和异步的方法:
pool.apply()  同步方法,进程池的同步方法,将任务变成串行,必须等任务执行结束才能给进程池提交下一个任务,可以直接拿到返回结果res
pool.apply_async()  异步方法,,可以直接拿到结果对象,从结果对象里面拿到结果,要用get方法,get方法会阻塞程序,没有拿到结果会一直等待.
pool.close()  锁住进程池,不在让其他的持续往程序里面人新任务,确保没有新的任务交给进程池里面的进程
join: 等待着进程池将自己里面的任务都执行完
进程池的同步方法:
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)
进程池的异步方法:
 
import time
from multiprocessing import Process,Pool
 
 
def f1(n):
    time.sleep(0.5)
    # print(n)
    return n*n
 
if __name__ == '__main__':
 
    pool = Pool(4)
 
    res_list = []
    for i in range(10):
        print('xxxx')
        #异步给进程池提交任务
        res = pool.apply_async(f1,args=(i,))
        res_list.append(res)
 
    # print('等待所有任务执行完')
    # pool.close()  #锁住进程池,意思就是不让其他的程序再往这个进程池里面提交任务了
    # pool.join()
 
    #打印结果,如果异步提交之后的结果对象
    for i in res_list:
        print(i.get())
进程池的同步和异步的综合:
import time
from multiprocessing import Process,Pool
 
def f1(n):
    time.sleep(0.5)
    # print(n)
    return  n*n
 
if __name__ == '__main__':
    pool =Pool(4)
    # pool.apply(f1,args=(2,))  #同步方法
    res_list = []
    for i in range(10):
        # print('任务%s' %i)
        #进程池的同步方法,将任务变成串行
        # res = pool.apply(f1,args=(i,))
        # print(res)
        #进程池的异步方法
        res =pool.apply_async(f1,args=(i,))
        print(res)
        # as_result =res.get()  #join的效果
        # print(as_result)
        res_list.append(res)
 
    pool.close() # 锁住进程池,不在让其他的程序网里面仍新的任务了,确保没有新的任务交给进程池里面的进程
    pool.join()
 
    for r in res_list:
        print(r.get())
 
    time.sleep(2)
    #主进程运行结束,进程池里面的任务全部停止,不会等待进程池里面的任务
    print('主进程直接结束')
    p = Process(target=f1,)
5.进程池的回调函数
 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)
    # print('回调函数中的结果:',s.get())
 
if __name__ == '__main__':
    pool = Pool(4)
    res = pool.apply_async(f1,args=(5,),callback=call_back_func)
    pool.close()
    pool.join()
    # print(res.get())
    print('主进程的进程id',os.getpid())
 
1.管道(了解)
Pipe(): 在进程之间建立一条通道,并返回元组(conn1,conn2),其中conn1,conn2表示管道两端的连接对象,强调一点:必须在产生Process对象之前产生管道.
from multiprocessing import Process,Pipe
conn1,conn2 = Pipe()  结构
主要方法:
conn1.recv():接受conn2.send(obj)发送的对象.如果没有消息可接受, recv方法会一直阻塞.如果连接的另一端已经关闭,那么recv方法会跑输EOEError.
conn1.send(obj):通过连接发送对象.obj是与序列化兼容的任意对象
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('我是主进程')
2.信号量  Semaphore
互斥锁同时只允许一个线程更改熟路,而信号量时同事允许一定数量的线程更改数据
s=Semaphore() 内部维护了一个计数器,acquire -1,release +1,为0的时候,其他的进程都要在acquire之前等待
s.acquire()
需要锁住的代码
s.release()
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)
 
    for i in range(10):
        p = Process(target=f1,args=(i,s))
 
        p.start()
3.事件 Event
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())
 
print('进程运行到这里')
e.set() #将e的状态更改为True
print('e的状态是:',e.is_set())
 
e.clear() #将e的状态更改为False
e.wait()  #e这个事件对象如果值为False,就在我加wait的地方等待
print('进程过了wait')
 基于事件的进程通信:
import time
from multiprocessing import  Process,Event
 
def f1(e):
    time.sleep(2)
    n = 100
    print('子进程计算结果为',n)
    e.set()
 
if __name__ == '__main__':
    e = Event()
    p = Process(target=f1,args=(e,))
    p.start()
 
    print('主进程等待....')
    e.wait()
    print('结果已经写入文件,可以拿到值')
4.进程池(重点) Pool 池子
对比:多进程和多进程池的效率对比:进程的创建和销毁时很消耗的,影响代码执行效率
pool.map() 参数数据必须是可迭代的,异步提交任务,自带close和join功能
import time
from multiprocessing import Process,Pool
 
 
# def f1(n):
#     time.sleep(1)
#     print(n)
 
#对比多进程和进程池的效率
def f1(n):
    for i in range(5):
        n = n + i
if __name__ == '__main__':
    #统计进程池执行100个任务的时间
    s_time = time.time()
    pool = Pool(4)  #里面这个参数是指定进程池中有多少个进程用的,4表示4个进程,如果不传参数,默认开启的进程数一般是cpu的个数
    # pool.map(f1,[1,2])  #参数数据必须是可迭代的
    pool.map(f1,range(100))  #参数数据必须是可迭代的,异步提交任务,自带join功能
    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)
        # p.join()
    [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
进程池的同步和异步的方法:
pool.apply()  同步方法,进程池的同步方法,将任务变成串行,必须等任务执行结束才能给进程池提交下一个任务,可以直接拿到返回结果res
pool.apply_async()  异步方法,,可以直接拿到结果对象,从结果对象里面拿到结果,要用get方法,get方法会阻塞程序,没有拿到结果会一直等待.
pool.close()  锁住进程池,不在让其他的持续往程序里面人新任务,确保没有新的任务交给进程池里面的进程
join: 等待着进程池将自己里面的任务都执行完
进程池的同步方法:
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)
进程池的异步方法:
 
import time
from multiprocessing import Process,Pool
 
 
def f1(n):
    time.sleep(0.5)
    # print(n)
    return n*n
 
if __name__ == '__main__':
 
    pool = Pool(4)
 
    res_list = []
    for i in range(10):
        print('xxxx')
        #异步给进程池提交任务
        res = pool.apply_async(f1,args=(i,))
        res_list.append(res)
 
    # print('等待所有任务执行完')
    # pool.close()  #锁住进程池,意思就是不让其他的程序再往这个进程池里面提交任务了
    # pool.join()
 
    #打印结果,如果异步提交之后的结果对象
    for i in res_list:
        print(i.get())
进程池的同步和异步的综合:
import time
from multiprocessing import Process,Pool
 
def f1(n):
    time.sleep(0.5)
    # print(n)
    return  n*n
 
if __name__ == '__main__':
    pool =Pool(4)
    # pool.apply(f1,args=(2,))  #同步方法
    res_list = []
    for i in range(10):
        # print('任务%s' %i)
        #进程池的同步方法,将任务变成串行
        # res = pool.apply(f1,args=(i,))
        # print(res)
        #进程池的异步方法
        res =pool.apply_async(f1,args=(i,))
        print(res)
        # as_result =res.get()  #join的效果
        # print(as_result)
        res_list.append(res)
 
    pool.close() # 锁住进程池,不在让其他的程序网里面仍新的任务了,确保没有新的任务交给进程池里面的进程
    pool.join()
 
    for r in res_list:
        print(r.get())
 
    time.sleep(2)
    #主进程运行结束,进程池里面的任务全部停止,不会等待进程池里面的任务
    print('主进程直接结束')
    p = Process(target=f1,)
5.进程池的回调函数
 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)
    # print('回调函数中的结果:',s.get())
 
if __name__ == '__main__':
    pool = Pool(4)
    res = pool.apply_async(f1,args=(5,),callback=call_back_func)
    pool.close()
    pool.join()
    # print(res.get())
    print('主进程的进程id',os.getpid())
 

day 32 管道,信号量,进程池,线程的创建的更多相关文章

  1. Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池

    Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...

  2. Python-GIL 进程池 线程池

    5.GIL vs 互斥锁(*****) 1.什么是GIL(Global Interpreter Lock) GIL是全局解释器锁,是加到解释器身上的,保护的就是解释器级别的数据 (比如垃圾回收的数据) ...

  3. concurrent.futures模块(进程池/线程池)

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  4. 13 并发编程-(线程)-异步调用与回调机制&进程池线程池小练习

    #提交任务的两种方式 #1.同步调用:提交完任务后,就在原地等待任务执行完毕,拿到结果,再执行下一行代码,导致程序是串行执行 一.提交任务的两种方式 1.同步调用:提交任务后,就在原地等待任务完毕,拿 ...

  5. concurrent.futures模块(进程池&线程池)

    1.线程池的概念 由于python中的GIL导致每个进程一次只能运行一个线程,在I/O密集型的操作中可以开启多线程,但是在使用多线程处理任务时候,不是线程越多越好,因为在线程切换的时候,需要切换上下文 ...

  6. python并发编程-进程池线程池-协程-I/O模型-04

    目录 进程池线程池的使用***** 进程池/线程池的创建和提交回调 验证复用池子里的线程或进程 异步回调机制 通过闭包给回调函数添加额外参数(扩展) 协程*** 概念回顾(协程这里再理一下) 如何实现 ...

  7. Python学习之GIL&进程池/线程池

    8.6 GIL锁** Global interpreter Lock 全局解释器锁 实际就是一把解释器级的互斥锁 In CPython, the global interpreter lock, or ...

  8. Dalvik虚拟机进程和线程的创建过程分析

    从前面Dalvik虚拟机的运行过程分析一文可以知道,Dalvik虚拟机除了可以执行Java代码之外,还可以执行Native代码,也就是C/C++函数. 这些C/C++函数在执行的过程中,又可以通过本地 ...

  9. day 32 管道 事件 信号量 进程池

    一.管道(多个时数据不安全)   Pipe 类 (像队列一样,数据只能取走一次) conn1,conn2 = Pipe()     建立管道 .send()   发送 .recv()   接收 二.事 ...

随机推荐

  1. ffmpeg 简介及使用

    简介 ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url ...

  2. CI框架去除index.php

    打开apache的配置文件,conf/httpd.conf : LoadModule rewrite_module modules/mod_rewrite.so 把该行前的#去掉. 搜索 AllowO ...

  3. Ionic控件之——按钮(Button)

    Ionic提供丰富的按钮特性,足以满足大部分的按钮实现需求. 一.HTML实现一个简单按钮: <button class="button"> 我是按钮 </but ...

  4. Java学习---TCP Socket的学习

    基础知识 1. TCP协议 TCP是一种面向连接的.可靠的.基于字节流的运输层(Transport layer)通信协议.在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,UDP是同一层 ...

  5. 【Python学习】Python中的数据类型精度问题

    Python真的很神奇...神奇到没有直接的数据类型概念,并且精度可以是任意精度.想当初,第一次接触OI算法时,写得第一个算法就是高精度加法,捣鼓了半天.一切在Python看来,仅仅三行代码即可完成. ...

  6. oracle sql练习 菜鸟入门!

    进入公司 ,首先是进行SQL培训 一下是针对oracle的emp与dept表进行的基础查询 --1.选择部门30中的所有员工: ; --2.列出所有办事员(CLERK)的姓名,编号和部门编号: sel ...

  7. FTP(文件传输协议)工作原理

    目前在网络上,如果你想把文件和其他人共享.最方便的办法莫过于将文件放FTP服务器上,然后其他人通过FTP客户端程序来下载所需要的文件. 1.FTP架构 如同其他的很多通讯协议,FTP通讯协议也采用客户 ...

  8. python基础语法1

    一.基础语法 1.常量 python语言没有真正的常量,它只是字面常量. 2.变量 变量是一个指针,它指向一块内存. 变量的命名规则: 1)只能包含字母.数字和下划线: 2)只能以字母或者下划线开始: ...

  9. 10G client连接数据库

    tnsnames.ora文件中的名字一定要顶格写(前面不留空格),不然连接时会如下报错. 已使用的参数文件:F:\oracle\product\10.2.0\client_1\network\admi ...

  10. Android Proguard使用技巧

    1.混淆后解码 ProGuard运行结束后,输出以下文件: dump.txt :描述.apk文件中所有类文件间的内部结构 mapping.txt:列出了原始的类,方法和字段名与混淆后代码间的映射.这个 ...