併發編程:
1. 進程、線程、協程的區別?
2. 線程
- 基本寫法編程
import threading # 1. 計算密集型多線程無用 v1 = [11,22,33] # +1 v2 = [44,55,66] # 100 def func(data,plus): for i in range(len(data)): data[i] = data[i] + plus t1 = threading.Thread(target=func,args=(v1,1)) t1.start() t2 = threading.Thread(target=func,args=(v2,100)) t2.start() # 2. IO操做 多線程有用 import threading import requests import uuid url_list = [ 'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg', 'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg', 'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg', ] def task(url): ret = requests.get(url) file_name = str(uuid.uuid4()) + '.jpg' with open(file_name, mode='wb') as f: f.write(ret.content) for url in url_list: t = threading.Thread(target=task,args=(url,)) t.start()
- 實例化
- 繼承
- 鎖
- RLock
- 線程池
3. 進程
- 基本寫法
- 實例化
- 繼承
- 鎖
- RLock
...
- 線程池
- 進程數據共享
4. 協程
- 協程
- 協程+IO:gevent
5. IO多路複用
1. IO多路複用多線程
IO多路複用做用:檢測多個socket是否已經發生變化(是否已經鏈接成功/是否已經獲取數據)(可讀/可寫)併發
2. 基於IO多路複用+socket實現併發請求(一個線程100個請求)app
IO多路複用 框架
socket非阻塞 異步
基於事件循環實現的異步非阻塞框架:lzlscrapy
非阻塞:不等待socket
異步:執行完某我的物後自動調用我給他的函數。ide
Python中開源 基於事件循環實現的異步非阻塞框架 Twisted 函數
總結:
1. socket默認是不是阻塞的?阻塞體如今哪裏?
2. 如何讓socket編程非阻塞?
3. IO多路複用做用?
檢測多個socket是否發生變化。
操做系統檢測socket是否發生變化,有三種模式:
select:最多1024個socket;循環去檢測。
poll:不限制監聽socket個數;循環去檢測(水平觸發)。
epoll:不限制監聽socket個數;回調方式(邊緣觸發)。
Python模塊:
select.select
select.epoll
4. 提升併發方案:
- 多進程
- 多線程
- 異步非阻塞模塊(Twisted) scrapy框架(單線程完成併發)
5. 什麼是異步非阻塞?
- 非阻塞,不等待。
好比建立socket對某個地址進行connect、獲取接收數據recv時默認都會等待(鏈接成功或接收到數據),才執行後續操做。
若是設置setblocking(False),以上兩個過程就再也不等待,可是會報BlockingIOError的錯誤,只要捕獲便可。
- 異步,通知,執行完成以後自動執行回調函數或自動執行某些操做(通知)。
好比作爬蟲中向某個地址baidu.com發送請求,當請求執行完成以後自執行回調函數。
6. 什麼是同步阻塞?
- 阻塞:等
- 同步:按照順序逐步執行
key_list = ['alex','db','sb']
for item in key_list:
ret = requests.get('https://www.baidu.com/s?wd=%s' %item)
print(ret.text)
7. 概念
以前:
# 你寫的代碼:7000w
v = [
[11,22], # 每一個都有一個append方法
[22,33], # 每一個都有一個append方法
[33,44], # 每一個都有一個append方法
]
# 王思聰
for item in v:
print(item.append)
以後:
class Foo(object):
def __init__(self,data,girl):
self.row = data
self.girl = girl
def append(self,item):
self.row.append(item)
v = [
Foo([11,22],'雪梨'), # 每一個都有一個append方法
Foo([22,33],'冰糖'), # 每一個都有一個append方法
Foo([33,44],'糖寶'), # 每一個都有一個append方法
]
for item in v:
print(item.append)
item.girl
6. 異步/同步 阻塞/非阻塞
import threading
# 1. 計算密集型多線程無用
v1 = [11,22,33] # +1
v2 = [44,55,66] # 100
def func(data,plus):
for i in range(len(data)):
data[i] = data[i] + plus
t1 = threading.Thread(target=func,args=(v1,1))
t1.start()
t2 = threading.Thread(target=func,args=(v2,100))
t2.start()
# 2. IO操做 多線程有用
import threading
import requests
import uuid
url_list = [
'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg',
'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg',
'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg',
]
def task(url):
ret = requests.get(url)
file_name = str(uuid.uuid4()) + '.jpg'
with open(file_name, mode='wb') as f:
f.write(ret.content)
for url in url_list:
t = threading.Thread(target=task,args=(url,))
t.start()