進程
1.是一個執行中的程序
2.每個進程都擁有自己的地址空間、內存、數據棧以及其他用於跟蹤執行的輔助數據
3.操作系統管理其上所有進程的執行,併爲這些進程合理地分配時間
4.進程也可通過派生(fork 或 spawn)新的進程來執行其他任務
線程
- 在 同一個進程下執行,並共享相同的上下文
- 一個進程中的各個線程與主線程共享同一片數據空間
- 線程包括開始、執行順序和結束三部分
- 它可以被搶佔(中斷)和臨時掛起(也稱爲睡眠)——讓步
- 一般是以併發方式執行
併發
- 等同於並行處理?
- 是一種屬性——程序、算法或問題的屬性
- 並行只是併發問題的可能方法之一
- 如果兩個事件互不影響,則兩個事件是併發的
對多核的利用
- 單核CPU系統中,不存在真正的併發
- GIL——全局解釋器鎖
- GIL只是強制在任何時候只有一個線程可以執行Python代碼
- I/O密集型應用(對讀寫頻繁)與CPU密集型應用(運算量大)
GIL執行順序
1.設置GIL
2.切換進一個線程取運行
3.執行下面操作之一:
指定數量的字節碼指令
線程主動讓出控制權(可以調用time.sleep(0)來完成)
6. 把線程設置回睡眠狀態(切換出線程)
7. 解鎖GIL
8. 重複上述步驟
實現一個線程
1.用threading模塊代替thread
2.用threading.Thread創建線程
3.start()啓動線程
4.join()掛起線程
threading模塊對象
對象 | 描述 |
---|---|
Thread | 表示一個執行線程的對象 |
Lock | 鎖原語對象(和thread模塊中的鎖一樣) |
Rlock | 可重入鎖對象,使單一線程可以(再次)獲得已持有的鎖(遞歸鎖) |
Condition | 條件變量對象,使得一個線程等待另一個線程滿足特定的“條件” ,比如改變狀態或某個數據值 |
Event | 條件變量的通用版本,任意數量的線程等待某個事件的發生,在該事件發生後所有線程將被激活 |
Semaphore | 爲線程間共享的有限資源提供了一個“計數器” |
BoundedSemaphore | 與Semaphore相似,不過它不允許超過初始值 |
Timer | 與Thread相似,不過它要在運行前等待一段時間 |
Barrier | 創建一個“障礙”,必須達到指定數量的線程後纔可以繼續 |
thread對象數據屬性
屬性 | 描述 |
---|---|
name | 線程名 |
ident | 線程的標識符 |
daemon | 布爾標誌,表示這個線程是否是守護線程 |
thread 對象方法
屬性 | 描述 |
---|---|
_init_() | 實例化一個線程對象,需要有一個可調用的target,以及其參數args或kwargs |
start() | 開始執行該線程 |
run() | 定義線程功能的方法(通常在子類中被應用開發者重寫) |
join(timeout=None) | 直至啓動的線程終止之前一直掛起;除非給出了timeout(秒),否則會一直阻塞 |
getName() | 返回線程名 |
setName(name) | 設定線程名 |
isAlivel / is_alive() | 布爾標誌,表示這個線程是否還在存活 |
isDaemon() | 如果是守護線程,則返回True,否則,返回False |
setDaemon() | 把線程的守護標誌設定爲布爾值daemonic(必須在線程start()之前調用) |
```python 創建線程
import threading
def loop():
""" 新的線程執行的代碼 """
n = 0
while n<5:
print(n)
now_thread = threading.current_thread()
print('[loop]now thread name: {0}'.format(now_thread.name))
n += 1
def use_thread():
""" 使用線程來實現 """
t = threading.Thread(target=loop, name='loop_thread1')
# 啓動線程
t.start()
# 掛起線程
t.join()
if __name__ == '__main__':
use_thread()
```python 創建線程類
import threading
class LoopThread(threading.Thread):
""" 自定義線程 """
n = 0
def run(self):
while self.n < 5:
print(self.n)
now_thread = threading.current_thread()
print('[loop]now thread name: {0}'.format(now_thread.name))
self.n += 1
if __name__ == '__main__':
# 當前正在執行的線程名稱
now_thread = threading.current_thread()
print('now thread name: {0}'.format(now_thread.name))
t = LoopThread(name="loop_thread_oop")
t.start()
t.join()
鎖
Lock() 無法重複鎖
Rlock() 同一線程內,能重複鎖
線程的調度和優化
線程池
進程之間的通信
Queue
協程
協程就是協同多任務
協程在一個進程或者是一個線程中執行
不需要鎖機制
對多核cpu的利用——多進程+協程