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. 前端jquery 获取select多选的值

    当select设置属性multiple='multiple'时, option就可以多选了  那么我们如何获取所有被选中的option的值呢? 首先说明: $('select[name="m ...

  2. Python——Pycharm打包exe文件

    一.安装pyinstraller    pip install  PyInstaller 二.打包程序   pyinstaller.py -F -w -i tubiao.ico 文件名.py -F 表 ...

  3. Django之ContentType组件

    一.理想表结构设计 1.初始构建 1. 场景刚过去的双12,很多电商平台都会对他们的商品进行打折促销活动的,那么我们如果要实现这样的一个场景,改如何设计我们的表? 2. 初始表设计 注释很重要,看看吧 ...

  4. C++ bitset 常用函数及运算符

    C++ bitset--高端压位卡常题必备STL 以下内容翻译自cplusplus.com,极大地锻炼了我的英语能力. bitset存储二进制数位. bitset就像一个bool类型的数组一样,但是有 ...

  5. poj 2955 Brackets (区间dp 括号匹配)

    Description We give the following inductive definition of a “regular brackets” sequence: the empty s ...

  6. UOJ#348 州区划分

    解:有一个很显然的状压...... 就设f[s]表示选的点集为s的时候所有方案的权值和. 于是有f[s] = f[s \ t] * (sum[t] / sum[s])P. 这枚举子集是3n的. 然后发 ...

  7. 深入剖析Kubernetes学习笔记:开篇词(00)

    一.关于Kubernetes初学的疑惑 就在这场因"容器"而起的技术变革中,kubernetes项目已经成为容器技术的事实标准,重新定义了基础设置领域对应用编排与管理的种种可能 1 ...

  8. [再寄小读者之数学篇](2014-06-22 最大值点处导数为零的应用 [中国科学技术大学2012 年高等数学B考研试题])

    设 $f(x)$ 在 $[0,1]$ 上连续, 在 $(0,1)$ 内可导, 且 $f(0)=f(1)=0$, $f\sex{\cfrac{1}{2}}=1$. 证明:对于任意的实数 $\lm$, 一 ...

  9. DataBase vs Data Warehouse

    Database https://en.wikipedia.org/wiki/Database A database is an organized collection of data.[1] A ...

  10. java(9)类和对象

    一.理解什么是类和对象 万事万物皆对象 1.1.属性——对象具有的特征(特点) 1.2.方法——对象可执行的操作(能干什么事) 1.3.对象的定义: 是一个客观存在的,看的见或摸得着的实体,由属性和方 ...