02 執行緒間通訊

2021-10-24 21:17:46 字數 3944 閱讀 3535

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類中呢?因為這些方法在操作同...