01、執行緒為什麼需要通訊
--執行緒會存在問題
--為什麼需要通訊:
--執行緒01:爬蟲乙個執行緒用於爬取主介面的url
--執行緒02:取出爬取到的url進行解析進一步獲取頁面html詳情
--使用 global定義全域性變數【共享變數】 || 使用引數傳值的方式也行,因為python傳遞的是物件的引用
import threading
import time
url_list =
def get_detail_html():
# 根據獲取到的url進一步訪問介面,得到詳細的html**
global url_list
while true:
if len(url_list):
url = url_list.pop()
print("get detail html_01 start")
print(url)
print("get detail html_01 and")
else:
break
def get_detail_url():
# 獲取主介面中的列表url,等待進一步訪問
global url_list
while true:
print("get detail html_02 start")
for i in range(20):
print("get detail html_02 and")
if __name__ == '__main__':
# 獲取url
thread_url = threading.thread(target=get_detail_url)
thread_url.start()
# 多執行緒列印url
for i in range(10):
thread_html = threading.thread(target=get_detail_html)
thread_html.start()
03、多執行緒使用queue進行通訊
--除非你對 執行緒鎖 足夠了解,否則不推薦使用共享變數
--queue物件及其屬性都是執行緒安全的
--執行緒安全就是多執行緒訪問時,採用了加鎖機制,當乙個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用。不會出現資料不一致或者資料汙染。
--執行緒不安全就是不提供資料訪問保護,有可能出現多個執行緒先後更改資料造成所得到的資料是髒資料
--檢視queue的方法:點開pycharm左邊和project一列的structure,可以看到物件的結構、變數和屬性
--put:put方法是往queue中壓入資料
--get: get方法是從queue中取出物件,queue.get()時如果queue為空會使執行緒阻塞在此處,直至獲取到資料
--qsize: 獲取佇列的長度 queue.qsize()
--put_nowait 和 get_nowait:在從佇列取資料 和 往佇列放資料時,無需等待其執行結束就返回,這是乙個非同步方法
--queue.put(item, block=true, timeout=none):
--block: 表示設定是否等待佇列操作完畢
--timeout: 表示等待時間多長以後即刻返回
--使用佇列進行通訊的**示例:
import threading
import time
from queue import queue
def get_detail_html(queue):
# 根據獲取到的url進一步訪問介面,得到詳細的html**
while true:
url = queue.get()
print("get detail html_01 start")
print(url)
print("get detail html_01 and")
def get_detail_url(queue):
# 獲取主介面中的列表url,等待進一步訪問
while true:
print("get detail html_02 start")
for i in range(20):
queue.put("".format(i))
print("get detail html_02 and")
if __name__ == '__main__':
# 申明佇列 queue
details_queue = queue(maxsize=1000)
# 獲取url
thread_url = threading.thread(target=get_detail_url, args=(details_queue,))
thread_url.start()
# 多執行緒列印url
for i in range(10):
thread_html = threading.thread(target=get_detail_html, args=(details_queue,))
thread_html.start()
--成對使用 queue.task_done() 和 queue.join(),對程式進行控制
import threading
import time
from queue import queue
len_url = 0
len_out = 0
def get_detail_html(queue):
# 根據獲取到的url進一步訪問介面,得到詳細的html**
while true:
global len_out
if queue.qsize() > 0:
url = queue.get()
print(url)
len_out += 1
print("len_out: {}".format(len_out))
else:
break
queue.task_done()
print("獲取詳情頁結束啦!!!!!!!!!")
def get_detail_url(queue):
# 獲取主介面中的列表url,等待進一步訪問
while true:
global len_url
if len_url <= 1000:
for i in range(1001):
queue.put("".format(i))
len_url += 1
print("len_url: {}".format(len_url))
else:
break
queue.join()
print("生產者也結束啦###################")
if __name__ == '__main__':
# 申明佇列 queue
details_queue = queue(maxsize=1000)
# 獲取url
thread_url = threading.thread(target=get_detail_url, args=(details_queue,))
thread_url.start()
# 多執行緒列印url
for i in range(10):
thread_html = threading.thread(target=get_detail_html, args=(details_queue,))
thread_html.start()
# # 佇列阻塞
# details_queue.task_done()
# details_queue.join()
執行緒間通訊
執行緒間通訊 多個執行緒在操作統一資源,但各個執行緒操作的動作不同。資源 class res class input implements runnable public void run else x x 1 2 class output implements runnable public vo...
執行緒間通訊
執行緒間的通訊 在乙個多執行緒的應用程式中,所有執行緒共享程序資源,協同工作。所以,執行緒之間的通訊是編寫多執行緒 應用的必不可少的環節。執行緒之間的通訊包括互斥 同步等,它是多 執行緒設計中最難控制的部分,也是關鍵部分。執行緒間的互斥 1 臨界區 在乙個多執行緒 的應用程式中,可能存在這樣的危險 ...
執行緒間通訊
執行緒間通訊 其實就是多個執行緒在操作同乙個資源 但是操作的動作不同。等待喚醒機制 wait notify 0 notifyall 都使用在同步中,因為要對持有監視器 鎖 的執行緒操作。所以要使用在同步中,因為只有同步才具有鎖 為什麼這些操作執行緒的方法要定義object類中呢?因為這些方法在操作同...