线程和进程 4

一、multiprocessing模块

  multiprocessing包是Python中的多进程管理包。
与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。该进程可以运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。

1, python的Process类的进程调用

 ##############  进程调用
# 调用进程模块和时间模块,并测试多进程功能 from multiprocessing import Process
import time def pp(name):
"""
函数:完成进程调用测试工作
:return:
"""
print("you are coming!",name,time.ctime())
time.sleep(2) if __name__ == '__main__':
p_list = [] # 开三个分进程,程序本身算主进程
for i in range(3):
p = Process(target=pp,args=("%s" %i,)) # 调用方式基本和thread相似
p_list.append(p)
p.start() for j in p_list: # 分别阻断进程和主进程间关系
j.join() print("end!",time.ctime())

2,继承类的调用方式

 ######## 继承Process类调用
# from multiprocessing import Process
import time class MyProcess(Process):
"""
继承父类Process的所用属性和功能
"""
def __init__(self):
Process.__init__(self) # 继承父类的所有__init__属性 # 实例执行start时,自动触发run的执行,可查看系统源码追溯到
def run(self):
print("Welcome to beijing!",self,time.ctime())
time.sleep(2) if __name__ == '__main__':
p_list = []
for i in range(3):
xx = MyProcess()
xx.start()
p_list.append(xx) for j in p_list:
j.join() print("END!",time.ctime())

二、进程间的通讯

2、1  进程队列queue

 from multiprocessing import Process,Queue

 def xx(q,n):
q.put(n*n+6)
# 测试子线程队列的位置
print("son process of:",id(q)) if __name__ == '__main__':
q = Queue()
# 测试主线程队列的位置
print("main process of: ",id(q)) for i in range(3):
p = Process(target=xx,args=(q,i,))
p.start() print(q.get())
print(q.get())
print(q.get()) '''
# 事实是为了证明:Queue虽然实现了线程间的交流,但是实际是在不同线程开辟了不一样的内存空间。然而linux优化,结果就如下了:mac是一样的
main process of: 4319925192
son process of: 4319925192
6
son process of: 4319925192
7
son process of: 4319925192
10
'''

2、2 进程管道 Pipe

 ############## Pipe 进程管道
"""
Pipe()返回的两个连接对象代表管道的两端。
每个连接对象都有send()和recv()方法(等等)。
请注意,如果两个进程(或线程)尝试同时读取或写入管道的同一端,管道中的数据可能会损坏。
""" from multiprocessing import Process,Pipe def x_l(l_conn):
"""
开辟一个进程负责lc的通话
:param l_conn:
:return:
"""
l_conn.send("Welcome to beijing!")
response = l_conn.recv()
print("x:",response)
l_conn.close() if __name__ == '__main__':
x_conn,l_conn = Pipe()
p = Process(target=x_l,args=(l_conn,)) # 开子进程,负责lc
p.start()
res = x_conn.recv()
print("l:",res)
x_conn.send("Im coming!")
p.join() """
l: Welcome to beijing!
x: Im coming!
"""

2,3 Manager 数据共享

 ############## Manager 数据共享:一个数据去更改另一个进程里的数据

 from multiprocessing import Manager,Process

 def xl(Mlist,i):
Mlist.append(i) if __name__ == '__main__':
manager = Manager() # 实例一个Manager
Mlist = manager.list([1,"a"]) # 数据共享类型为列表,也可以用字典等
l = [] # 开子进程,并往主线程共享列表添加变量
for i in range(5):
p = Process(target=xl,args=(Mlist,i,))
p.start()
l.append(p) for j in l:
j.join() print(Mlist

2,4 Pool 进程池

 ############## Pool
"""
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,
如果进程池序列中没有可供使用的进进程,那么程序就会等待,
直到进程池中有可用进程为止。
"""
from multiprocessing import Pool
import time def xl(n):
print(n)
time.sleep(2)
print("END!") if __name__ == '__main__':
pool_obj = Pool() # 进程池,默认进程数是cpu核数,其中os.cpu_count()查看
for i in range(20):
pool_obj.apply_async(func=xl,args=(i,))
pool_obj.close() # 执行后,不会有新等进程进入进程池
pool_obj.join() # join()在close()之后,套路,牢记!!! print("ALL IS OVER!")
 p.apply(func [, args [, kwargs]]):在一个池工作进程中执行func(*args,**kwargs),然后返回结果。需要强调的是:此操作并不会在所有池工作进程中并执行func函数。如果要通过不同参数并发地执行func函数,必须从不同线程调用p.apply()函数或者使用p.apply_async()
p.apply_async(func [, args [, kwargs]]):在一个池工作进程中执行func(*args,**kwargs),然后返回结果。此方法的结果是AsyncResult类的实例,callback是可调用对象,接收输入参数。当func的结果变为可用时,将理解传递给callback。callback禁止执行任何阻塞操作,否则将接收其他异步操作中的结果。 p.close():关闭进程池,防止进一步操作。如果所有操作持续挂起,它们将在工作进程终止前完成5 P.jion():等待所有工作进程退出。此方法只能在close()或teminate()之后调用

三, 协程

 """
协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
对比操作系统控制线程的切换,用户在单线程内控制协程的切换,优点如下:
1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级
2. 单线程内就可以实现并发的效果,最大限度地利用cpu
"""
 import time

 """
传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。
如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高。
"""
# 注意到consumer函数是一个generator(生成器):
# 任何包含yield关键字的函数都会自动成为生成器(generator)对象 def consumer():
r = ''
while True:
# 3、consumer通过yield拿到消息,处理,又通过yield把结果传回;
# yield指令具有return关键字的作用。然后函数的堆栈会自动冻结(freeze)在这一行。
# 当函数调用者的下一次利用next()或generator.send()或for-in来再次调用该函数时,
# 就会从yield代码的下一行开始,继续执行,再返回下一次迭代结果。通过这种方式,迭代器可以实现无限序列和惰性求值。
n = yield r
if not n:
return
print('[CONSUMER] ←← Consuming %s...' % n)
time.sleep(1)
r = '200 OK'
def produce(c):
# 1、首先调用c.next()启动生成器
next(c)
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] →→ Producing %s...' % n)
# 2、然后,一旦生产了东西,通过c.send(n)切换到consumer执行;
cr = c.send(n)
# 4、produce拿到consumer处理的结果,继续生产下一条消息;
print('[PRODUCER] Consumer return: %s' % cr)
# 5、produce决定不生产了,通过c.close()关闭consumer,整个过程结束。
c.close()
if __name__=='__main__':
# 6、整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。
c = consumer()
produce(c) '''
result: [PRODUCER] →→ Producing 1...
[CONSUMER] ←← Consuming 1...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] →→ Producing 2...
[CONSUMER] ←← Consuming 2...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] →→ Producing 3...
[CONSUMER] ←← Consuming 3...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] →→ Producing 4...
[CONSUMER] ←← Consuming 4...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] →→ Producing 5...
[CONSUMER] ←← Consuming 5...
[PRODUCER] Consumer return: 200 OK
'''

3,1 Gevent

 #############   协程 greenlet

 from gevent import monkey
monkey.patch_all()
import gevent
from urllib import request
import time def xl(url):
print("GET:%s" %url)
res = request.urlopen(url)
data = res.read()
print("%d bytes recevied from %s" %(len(data),url)) start = time.time() gevent.joinall([
# gevent.spawn(xl,"http://www.xiaohuar.com"),
gevent.spawn(xl,"http://www.mmjpg.com"),
gevent.spawn(xl,"http://www.fengniao.com")
]) print(time.time()-start)
 
 
Greenlet
Gevent 自动切换的牛逼之处,可以的就开干 

Day 32 process&threading_4的更多相关文章

  1. pandas基本操作2

    1.axes返回标签列表 import pandas as pd import numpy as np dates = pd.date_range(', periods=8) df = pd.Data ...

  2. Tensorflow样例代码分析cifar10

    github地址:https://github.com/tensorflow/models.git 本文分析tutorial/image/cifar10教程项目的cifar10_input.py代码. ...

  3. pow求一个数的n次幂

    #!/usr/bin/env python i = pow(2,5) #求一个数的n次幂 print(i) C:\Python35\python3.exe F:/Python/2day/c6.py 3 ...

  4. Retrieving data from a server

    A system includes a server and a controller embedded in a device. Both the server and the embedded c ...

  5. vue-cli2、vue-cli3脚手架详细讲解

    前言: vue脚手架指的是vue-cli它是vue官方提供的一个快速构建单页面(SPA)环境配置的工具,cli 就是(command-line-interface  ) 命令行界面 .vue-cli是 ...

  6. 使用UI Automation实现自动化测试--1-4

    Introduction UI Automation是Microsoft .NET 3.0框架下提供的一种用于自动化测试的技术,是在MSAA基础上建立的,MSAA就是Microsoft Active ...

  7. python10

     一.多进程multiprocessing multiprocessing包是Python中的多进程管理包.与threading.Thread类似,它可以利用multiprocessing.Proce ...

  8. Stream中的Peek操作

    1.引言 如果你试图对流操作中的流水线进行调试, 了解stream流水线每个操作之前和操作之后的中间值, 该如何去做? 首先我们看一个例子, 使用forEach将流操作的结果打印出来. 1 /** 2 ...

  9. [Chapter 3 Process]Practice 3.12 Including the initial parent process, how many processes are created by the program shown in Figure 3.32?

    3.12 Including the initial parent process, how many processes are created by the program shown in Fi ...

随机推荐

  1. ZendFramework-2.4 源代码 - 整体架构(类图)

  2. Vue钩子函数生命周期实例详解

    vue生命周期简介 Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁 ...

  3. ThinkPHP函数I代码优化

    ThinkPHP/Common/common.php 文件 I函数,主要用来获取一些gpc请求的变量的,函数有一部分代码是过滤变量的,每次都运行一次,其实是没有必要的. 如果你每次都像这样的方式调用的 ...

  4. 第1-5章 慕课网微信小程序开发学习笔记

    第1章 前言:不同的时代,不同的Web --微信小程序商城构建全栈应用 http://note.youdao.com/noteshare?id=a0e9b058853dbccf886c1a890594 ...

  5. Python知识点入门笔记——Python文件操作、异常处理及random模块使用

    文件是存储在外部介质的数据集合,通常可以长久保存,前提是介质不易损坏 Python的绝对路径写法: E:\\编程学习资料\\爬取某社区高清无码大图.py E:/编程学习资料/爬取某社区高清无码大图.p ...

  6. Python基础:输入与输出(I/O)

    来做一个NLP任务 步骤为: 1.读取文件: 2.去除所有标点符号和换行符,并把所有大写变成小写: 3.合并相同的词,统计每个词出现的频率,并按照词频从大到小排序: 4.将结果按行输出到文件 out. ...

  7. (转)iOS静态库与动态库的区别

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用 ...

  8. Union found

    Use array. class UnionFound { public: vector<int> v; int cnt; UnionFound(int n) { v = vector&l ...

  9. MongoDB集群部署 - 带访问控制的分片副本集

    1. 前言 Ceilometer将meter.event等数据保存在MongoDB中,之前将MongoDB部署在控制节点上,使用三副本模式,时间长了发现meter数据爆炸式增长,区区2T的磁盘捉襟见肘 ...

  10. ASP.NET下调用ffmpeg与mencoder实现视频转换截屏

    最近要做一个视频播放的系统,用到了ffmpeg和mencoder两个工具,查了一些资料,发现这方面的资料还挺多的,但是就是乱了一点,我自己从头整理了一下,和大家分享一下: 1.ffmpeg实现视频(a ...