Day 32 process&threading_4
线程和进程 4
一、multiprocessing模块
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)
Day 32 process&threading_4的更多相关文章
- pandas基本操作2
1.axes返回标签列表 import pandas as pd import numpy as np dates = pd.date_range(', periods=8) df = pd.Data ...
- Tensorflow样例代码分析cifar10
github地址:https://github.com/tensorflow/models.git 本文分析tutorial/image/cifar10教程项目的cifar10_input.py代码. ...
- pow求一个数的n次幂
#!/usr/bin/env python i = pow(2,5) #求一个数的n次幂 print(i) C:\Python35\python3.exe F:/Python/2day/c6.py 3 ...
- Retrieving data from a server
A system includes a server and a controller embedded in a device. Both the server and the embedded c ...
- vue-cli2、vue-cli3脚手架详细讲解
前言: vue脚手架指的是vue-cli它是vue官方提供的一个快速构建单页面(SPA)环境配置的工具,cli 就是(command-line-interface ) 命令行界面 .vue-cli是 ...
- 使用UI Automation实现自动化测试--1-4
Introduction UI Automation是Microsoft .NET 3.0框架下提供的一种用于自动化测试的技术,是在MSAA基础上建立的,MSAA就是Microsoft Active ...
- python10
一.多进程multiprocessing multiprocessing包是Python中的多进程管理包.与threading.Thread类似,它可以利用multiprocessing.Proce ...
- Stream中的Peek操作
1.引言 如果你试图对流操作中的流水线进行调试, 了解stream流水线每个操作之前和操作之后的中间值, 该如何去做? 首先我们看一个例子, 使用forEach将流操作的结果打印出来. 1 /** 2 ...
- [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 ...
随机推荐
- PHP 计算代码运行所占内存和时间
PHP 计算代码运行所占内存和时间 在PHP开发过程中,写出高质量的代码是很重要的,除了代码必须规范之外,性能也是不可忽视的一方面,那么如果检验一段代码是否高效呢,可通过以下一段php代码来粗略检测 ...
- JZOJ 1267. 路障
1267. 路障(block.pas/c/cpp) (File IO): input:block.in output:block.out Time Limits: 1000 ms Memory Li ...
- (转)CocoaPods
本文转自http://nshipster.cn/cocoapods/ 文明是建立在道路,桥梁,运河,下水道,管线,电线和光纤这些基础设施之上的.只要设计和施工得当,它们可以帮助社会成倍的发展. 唯一的 ...
- Codeforces Round #472 A-D
A题: 题意:就是给你一个长度为n的字符串,有三种颜色,其中有一些‘?’的字符代表未着色,你需要找到至少有两种方法染色,同时满足相邻两个字符间不能相同: 思路:有两种染色方法的前提:首先给定的字符串中 ...
- 洛谷 P1736 创意吃鱼法(多维DP)
题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...
- 快速从mysqldump文件中恢复一个表
快速从较大的mysqldump文件中恢复一个表到数据库中: 1.先获取目标表(md_gas_check_record)在文件中的位置 [publish@LF-PRO-DB-01 ~]$ cat dby ...
- Java面向对象---抽象类与接口
final关键字 1.final关键字在java中被称为完结器,表示最终的意思: 2.final能声明类.方法.属性: 3.使用final声明的类不能被继承,使用final声明的方法不能被重写,使用f ...
- Linux程序编辑器
重点回顾:Linux底下的配置文件多为文本文件,故使用vim即可进行设定编辑: vim可视为程序编辑器,可用以编辑shell script,配置文件等,避免打错字 vi为所有unix like的操作系 ...
- 1、HTML基础总结 part-1
1.基本标签属性 <html> <!--属性和属性值对大小写不敏感. 不过,万维网联盟在其 HTML 4 推荐标准中推荐小写的属性/属性值. 而新版本的 (X)HTML 要求使用小写 ...
- Python-S9——Day115-Flask Web框架
01 当日内容概要 1 当日内容概要 1.1 Flask基础: 1.2 Web框架包含的基础组件: 1.2.1 路由.视图函数.模板渲染: 1.3 Flask配置文件: 1.4 Flask的路由系统: ...