Python之路,Day9 - 线程、进程、协程和IO多路复用

参考博客:
线程、进程、协程:
http://www.cnblogs.com/wupeiqi/articles/5040827.html

http://www.cnblogs.com/alex3714/articles/5230609.html


IO多路复用:
http://www.cnblogs.com/wupeiqi/articles/5040823.html

 课堂笔记:

- 线程进程介绍
1. 工作最小单元是线程
2. 应用程序 -> 至少有一个进程 -> 至少有一个线程
3. 应用场景:
IO密集型:线程
计算密集型:进程
4. GIL,全局解释器锁。
- 保证同一个进程中只有一个线程同时被调度
- 线程
1. 基本使用
def task(arg):
time.sleep(arg)
print(arg)

for i in range(5):
t = threading.Thread(target=task,args=[i,])
# t.setDaemon(True) # 主线程终止,不等待子线程
# t.setDaemon(False)
t.start()
# t.join() # 一直等
# t.join(1) # 等待最大时间
2. 锁
# 1. 只能有一个人使用锁
# lock = threading.Lock() # 只能开一把
# lock = threading.RLock()# 可以开多把
# 2. 多个人同时使用锁
# lock = threading.BoundedSemaphore(3)
# 3. 所有的解脱锁的限制
# lock = threading.Event()
# 4. 肆意妄为
# lock = threading.Condition()

3. 线程池
模式一:直接处理
def task(url):
"""
任务执行两个操作:下载;保存本地
"""
# response中封装了Http请求响应的所有数据
# - response.url 请求的URL
# - response.status_code 响应状态码
# - response.text 响应内容(字符串格式)
# - response.content 响应内容(字节格式)
# 下载
response = requests.get(url)

# 下载内容保存至本地
f = open('a.log','wb')
f.write(response.content)
f.close()

pool = ThreadPoolExecutor(2)
url_list = [
'http://www.oldboyedu.com',
'http://www.autohome.com.cn',
'http://www.baidu.com',
]
for url in url_list:
print('开始请求',url)
# 去连接池中获取链接
pool.submit(task,url)


模式二:分步处理
def save(future):
"""
只做保存 # future中包含response
"""
response = future.result()

# 下载内容保存至本地
f = open('a.log','wb')
f.write(response.content)
f.close()

def task(url):
"""
只做下载 requests
"""
# response中封装了Http请求响应的所有数据
# - response.url 请求的URL
# - response.status_code 响应状态码
# - response.text 响应内容(字符串格式)
# - response.content 响应内容(字节格式)
# 下载
response = requests.get(url)
return response

pool = ThreadPoolExecutor(2)
url_list = [
'http://www.oldboyedu.com',
'http://www.autohome.com.cn',
'http://www.baidu.com',
]
for url in url_list:
print('开始请求',url)
# 去连接池中获取链接
# future中包含response
future = pool.submit(task,url)
# 下载成功后,自动调用save方法
future.add_done_callback(save)

- 进程
1. 基本使用
from multiprocessing import Process
import time
def task(arg):
time.sleep(arg)
print(arg)

if __name__ == '__main__':
for i in range(10):
p = Process(target=task,args=(i,))
p.daemon = True
# p.daemon = False
p.start()
p.join(1)

print('主进程最后...')

2. 进程之间的数据共享
特殊的东西
- Array(‘类型’,长度)
- Manager().list() / Manager().dict()

3. 进程池


================== 结论 ==================
IO密集:线程
计算密集:进程



- 协程
pip3 install greenlet
协程永远是一个线程在执行,对线程的一个分片处理。

二次加工:
自定义:
select实现
现成 :
pip3 install gevent

- IO多路复用
监听多个socket对象是否有变化(可读,可写,发送错误)
- 示例一:

- socketserverIO
- IO多路复用
- 线程
- 自定义异步非阻塞的框架


本周作业:
服务端:socketserver
用IO多路复用select,使用“伪”并发


客户端:
基本操作:
聊天
上传

尝试:
客户端是否可以用select来实现???


posted @ 2017-03-19 13:39  李永三  阅读(234)  评论(0编辑  收藏  举报