multiprocessing包是Python中的多进程管理包。与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。该进程可以运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境

调用方法一:

import multiprocessing#多进程包
import time
def visit(name):
time.sleep(1)
print('hello', name,time.ctime()) if __name__ == '__main__':
p_list=[]
for i in range(3):
p = multiprocessing.Process(target=visit, args=('alvin',))#创建子进程对象
p_list.append(p)
p.start()#开启进程
for i in p_list:
p.join()#与线程意义先疼痛
print('end')

调用方法二:

class MyProcess(Process):
def run(self):
time.sleep(1)
print ('hello', self.name,time.ctime()) if __name__ == '__main__':
p_list=[]
for i in range(3):
p = MyProcess()
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('end')

一:pid

class progress(multiprocessing.Process):
def run(self):
time.sleep(2)
print("process name",self.name)
print("parent process id",os.getppid(),time.time())
print("process id",os.getpid(),time.time())
if __name__=="__main__":
print("main process line")
progress.run(progress)
print("----------")
t1=progress()
t2=progress()
t1.start()
t2.start() #主进程的parent process id 33440 1550129555.0609472
#主进程的process id 21996 1550129555.0609472
#子进程
  process name progress-1
  parent process id 21996 1550129557.234302
  process id 29496 1550129557.234302

二:方法与属性

  • is_alive():返回进程是否在运行。

  • join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。

  • start():进程准备就绪,等待CPU调度

  • run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。

  • terminate():不管任务是否完成,立即停止工作进程

  • daemon:和线程的setDeamon功能一样

  • name:进程名字。

  • pid:进程号

一:进程队列queque

import multiprocessing,time
def foo(parad):
time.sleep(1)
print("子进程队列id",id(parad))
parad.put("name")
parad.put({"name":"alex"})
if __name__=="__main__":
p_list=[]
parad=multiprocessing.Queue()#创建一个进程队列
print("主进程队列",id(parad))
for i in range(3):
progress=multiprocessing.Process(target=foo,args=(parad,))
progress.start()
print(parad.get())
print(parad.get())

二:管道pipe

  • pipe()函数返回一对通过一个双向管道链接的链接对象  
  • parent_conn, child_conn = multiprocessing.Pipe()#创建一个管道对象
  • parent_conn.recv()#接收 parent_conn.send()#发数据
def foo(conn):
time.sleep(1)
conn.send("hellow father")
print("子进程收:",conn.recv())
conn.close()
if __name__=="__main__":
parent_conn, child_conn = multiprocessing.Pipe()#创建一个管道对象
progress=multiprocessing.Process(target=foo,args=(child_conn,))#将管道一方传送到子进程
progress.start()
print("主线程收:",parent_conn.recv())#接收数据
parent_conn.send("hellow son")#发送数据
progress.join()
print("ending...")
  • The two connection objects returned by Pipe() represent the two ends of the pipe. Each connection object has send() and recv() methods (among others). Note that data in a pipe may become corrupted if two processes (or threads) try to read from or write to the same end of the pipe at the same time. Of course there is no risk of corruption from processes using different ends of the pipe at the same time

三:manager

Queue和pipe只是实现了数据交互,并没实现数据共享,即一个进程去更改另一个进程的数据。

A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies.

A manager returned by Manager() will support types listdictNamespaceLockRLockSemaphoreBoundedSemaphoreConditionEventBarrierQueueValue and Array. For example:

def foo(dict,list,i,string):
dict["name"]="tom"
list[0]=5
list.append(i)
string="i am tom"
print("son process",id(dict),id(list))
if __name__=="__main__":
with multiprocessing.Manager() as manager:
dict=manager.dict({"name":"alex"})
list=manager.list([1,2,3,4])
string=manager.Value(value="i am alex",typecode=int)
p_list=[]
for i in range(2):
progress=multiprocessing.Process(target=foo,args=(dict,list,i,string))
p_list.append(progress)
progress.start() for i in p_list:
i.join()
print(dict)
print(list)
print(string)
print("father process", id(dict), id(list))

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止

进程池中的方法:

  • apply 从进程池里取一个进程并同步执行
  • apply_async 从进程池里取出一个进程并异步执行
  • terminate 立刻关闭进程池
  • join 主进程等待所有子进程执行完毕,必须在close或terminete之后
  • close 等待所有进程结束才关闭线程池
·

 import multiprocessing,time,os
def foo(i):
time.sleep(1)
print(i,time.time())
print("son",os.getpid())#
def success(arg):
print("success",os.getpid())#
def fail(arg):
print("falid")
if __name__ == '__main__':
print("main:",os.getpid())#
pool=multiprocessing.Pool()
lock=multiprocessing.Lock()
for i in range(20):
pool.apply_async(func=foo,args=(i,),callback=success,error_callback=fail)
#pool.apply(func=foo,args=(i,))
pool.close()
pool.join()
print("ending....")

进程池

所谓协程又称为微线程,我们在进程在创建时, 需要耗费时间和cpu资源;在创建多线程时,也需要消耗时间和资源。利用多协程的运行过程中,始终只要一个线程, 不存在创建线程和销毁线程需要的时间; 也没有线程切换的开销, 任务需要开启线程数越多, 协程的优势越明显;更不需要多线程的锁机制(GIL)。

协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。

协程的优点:

  (1)无需线程上下文切换的开销,协程避免了无意义的调度,由此可以提高性能(但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力)

  (2)无需原子操作锁定及同步的开销

  (3)方便切换控制流,简化编程模型

  (4)高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

协程的缺点:

  (1)无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。

  (2)进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

def consumer(name):
print("我要吃包子")
while True:
baozi=yield
print("%s eating %s 包子"%(name,baozi))
def producer(name):
c1.__next__()
c2.__next__()
n=0
while True:
print("\033[32;1m[producer]\033[0m is making baozi %s and %s" % (n, n + 1))
c1.send(n)
c2.send(n+1)
n+=2 if __name__ == '__main__':
c1=consumer("alex")
c2=consumer("tom")
p1=producer("cookie")

import greenlet
def test1():
print(12)
g2.switch()
print(34)
g2.switch()
print(96)
def test2():
print(56)
g1.switch()
print(78)
g1=greenlet.greenlet(test1)#创建一个协程对象
g2=greenlet.greenlet(test2)
g1.switch()#启动协程/切换协程

gevnet是协程之间的自动切换

import gevent
def func1():
print(12)
gevent.sleep(2)
print(56) def func2():
print(34)
gevent.sleep(1)
print(78)
t1=gevent.spawn(func1)#创建一个线程对象
t2=gevent.spawn(func2)
print(t1)
gevent.joinall([t1,t2])#添加线程对象,并运行线程

  

  

python第10天(上)的更多相关文章

  1. 深入理解Python异步编程(上)

    本文代码整理自:深入理解Python异步编程(上) 参考:A Web Crawler With asyncio Coroutines 一.同步阻塞方式 import socket def blocki ...

  2. python之实现ftp上传下载代码(含错误处理)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python之实现ftp上传下载代码(含错误处理) #http://www.cnblogs.com/kait ...

  3. 『Python基础-10』字典

    # 『Python基础-10』字典 目录: 1.字典基本概念 2.字典键(key)的特性 3.字典的创建 4-7.字典的增删改查 8.遍历字典 1. 字典的基本概念 字典一种key - value 的 ...

  4. 如何用Python在10分钟内建立一个预测模型

    转载自:https://baijia.baidu.com/s?old_id=307995 最近,我从孙子(指<孙子兵法>——译者注)那里学到了一些策略:速度和准备 “兵之情主速,乘人之不及 ...

  5. Python 3.10 版本采纳了首个 PEP,中文翻译即将推出

    现在距离 Python 3.9.0 的最终版本还有 3 个月,官方公布的时间线是: 3.9.0 beta 4: Monday, 2020-06-29 3.9.0 beta 5: Monday, 202 ...

  6. Python 3.10 的首个 PEP 诞生,内置类型 zip() 迎来新特性

    译者前言:相信凡是用过 zip() 内置函数的人,都会赞同它很有用,但是,它的最大问题是可能会产生出非预期的结果.PEP-618 提出给它增加一个参数,可以有效地解决大家的痛点. 这是 Python ...

  7. Python 3.10 明年发布,看看都有哪些新特性?

    我们目前生活在Python 3.8的稳定时代,上周发布了Python的最新稳定版本3.8.4.Python 3.9已经处于其开发的beta阶段,并且2020年7月3日预发布了beta版本(3.9.0b ...

  8. Python 学习笔记(上)

    Python 学习笔记(上) 这份笔记是我在系统地学习python时记录的,它不能算是一份完整的参考,但里面大都是我觉得比较重要的地方. 目录 Python 学习笔记(上) 基础知识 基本输入输出 模 ...

  9. Python 3.10 中新的功能和变化

    随着最后一个alpha版发布,Python 3.10 的功能更改全面敲定! 现在,正是体验Python 3.10 新功能的理想时间!正如标题所言,本文将给大家分享Python 3.10中所有重要的功能 ...

  10. Python 3.10 is coming!

    看看Python 官网的文档 whatsnew,Python 3.10 已然距离我们越来越近了,然我们看看 Python 3.10 相较于 Python 3.9 有哪些改变吧 新特性 通过括号来组织多 ...

随机推荐

  1. P4783 【模板】矩阵求逆

    原题链接 https://www.luogu.org/problemnew/show/P4783 一道模板题,更重要的省选难度..... 题目要求的是一个n*n的逆矩阵,还要对大数取膜. 普通高中生: ...

  2. ZOJ 4097 Rescue the Princess

    在这个物欲横流的社会 oj冷漠无情 只有这xx还有些温度 越界就越界吧  wrong 怎么回事.... 给出一个图 然后给出q次询问 问是否存在v和w分别到u的路径且边不重复 在边双连通分量中 任意两 ...

  3. [CTSC2008]网络管理 [整体二分]

    题面 bzoj luogu 所有事件按时间排序 按值划分下放 把每一个修改 改成一个删除一个插入 对于一个查询 直接查这个段区间有多少合法点 如果查询值大于等于目标值 进入左区间 如果一个查询无解 那 ...

  4. 【并发编程】一个最简单的Java程序有多少线程?

    一个最简单的Java程序有多少线程? 通过下面程序可以计算出当前程序的线程总数. import java.lang.management.ManagementFactory; import java. ...

  5. MongoDB介绍与安装

    MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是类似 json 的 bson 格式,因此可以存储比较复杂的数据 ...

  6. java 11 增加了一系列的字符串处理方法,Optional 加强 ,改进的文件API

    增加了一系列的字符串处理方法 如以下所示. // 判断字符串是否为空白 " ".isBlank(); // true // 去除首尾空白 " Javastack &quo ...

  7. python之OpenCv(三)---基本绘图

    opencv 提供了绘制直线.圆形.矩形等基本绘图的功能 1.绘直线 cv2.line(画布,起点坐标,终点坐标,颜色,宽度) 例如: cv2.line(image,(20,60),(300,400) ...

  8. busybox(三)最小根文件系统

    目录 busybox(三)最小根文件系统 引入 构建终端 构造inittab 配置应用程序 构建C库 制作映像文件yaffs title: busybox(三)最小根文件系统 tag: arm dat ...

  9. saltstack主机管理项目:编写插件基类-获取主机列表-提取yaml配置文件(四)

    一.编写插件基类 1.目录结构 1.我是如何获知我有多少种系统? 当客户端第一连接过来的时候,我就已经把这些文件存下来了 ,存在到哪里了?存到数据库了 每次对主机发送命令的动作时,我从库里把数据取出来 ...

  10. 如何巧妙的使用ArrayList的Clone方法

    一.ArrayList的Clone方法的源码 返回一个Object对象,所以在使用此方法的时候要强制转换. ArrayList的本质是维护了一个Object的数组,所以克隆也是通过数组的复制实现的,属 ...