併發編程總結

併發編程:
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()
相關文章
相關標籤/搜索