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. linux添加超级管理员用户,修改,删除用户

    useradd一个用户后,去修改/etc/passwd文件中的这个用户这一行,把其中的uid改为0,gid改为0(其中****代表一个用户名)这样****就具有root权限了 如:root2:x:0: ...

  2. [模板] dfs序, 树链剖分, 换根

    树链剖分 树链剖分是一种对树的分治, 可以把树上的任意一条链分解为 \(O(\log n)\) 条在dfs序上相邻的子链, 便于数据结构(如线段树)来维护. 另外, 子树在dfs序上也是一个连续的区间 ...

  3. 一文读懂ES6(附PY3对比)

      Ⅰ.ES6~POP¶ 代码示例:https://github.com/lotapp/BaseCode/tree/master/javascript/1.ES6 在线演示:https://githu ...

  4. 强化学习Q-Learning算法详解

    python风控评分卡建模和风控常识(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005214003&am ...

  5. JavaLinkedHashSet练习

    题目三: 1.键盘录入一个字符串,去掉其中重复字符 2.打印出不同的那些字符,必须保证顺序.例如输入:aaaabbbcccddd,打印结果为:abcd.尝试用两种方法解决字符串删除问题,一是使用Has ...

  6. 第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等)

    一. 语法糖简介   语法糖也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方 ...

  7. [物理学与PDEs]第3章第2节 磁流体力学方程组 2.2 考虑到电磁场的存在对流体力学方程组的修正

    1.  连续性方程 $$\bex \cfrac{\p \rho}{\p t}+\Div(\rho{\bf u})=0.  \eex$$ 2.  动量守恒方程 $$\bex \cfrac{\p }{\p ...

  8. 同步Name到Comment 及 同步 Comment 到Name

    在 PowerDesigner执行命令  Tools->Execute Commands->Edit/Run Scripts 代码一:将Name中的字符COPY至Comment中 Opti ...

  9. sqlmap基础入门超详细教程

    前言: 总算进入了自己喜欢的行业. 要时刻记得当初自己说过的话, 不忘初心. Come on! 资料: 感谢超哥分享的干货..  sqlmap干货点击直达 学习环境: 本次学习使用的是kali集成的s ...

  10. MacOS下好用的截图软件snip

    1 官网下载,腾讯出的 https://snip.qq.com/ 2 下一步下一步安装就好,然后设置一下自己喜欢的快捷键,我的是command + control+J,选择自己喜欢的或者默认都可以 3 ...