執行緒同步(lock、rlock、semaphores、condition)
concurrent執行緒池編碼
多程序程式設計-multiprocessing
程序間通訊
# gil global interpreter lock 全域性直譯器鎖
# python中的乙個執行緒對應於c語言中的乙個執行緒
# gil使得乙個時刻只有乙個執行緒在乙個cpu上執行位元組碼,無法將多個執行緒對映到多個cpu上執行
# gil會根據位元組碼行數以及時間片釋放gil,gil在遇到io的操作的時候主動釋放
普通樣式的多執行緒程式設計
import threading
import time
def get_html():
print("我開始爬取網頁了")
time.sleep(2)
print("網頁爬取完成")
def get_url():
print("我開始爬取url")
time.sleep(4)
print("url爬取完成")
if __name__ == "__main__":
thread1 = threading.thread(target=get_html)
thread2 = threading.thread(target=get_url)
start_time = time.time()
# setdaemon方法是將該程序設定成主線程的守護程序,即如果主線程執行完成,該子執行緒必須結束
# 該方法必須要在start方法之前設定
# 該方法預設為false
thread1.setdaemon(true)
thread2.setdaemon(true)
thread1.start()
thread2.start()
thread1.join() # 該方法會讓主線程等待子執行緒全部執行完成後,才會執行下面的**
thread2.join()
print("工作完成,用時{}".format(time.time() - start_time))
使用繼承方法實現多執行緒
import threading
class getdetaihtml(threading.thread):
"""類繼承thread類必須重寫run方法
"""def __init__(self, name):
super().__init__(name = name)
def run(self):
print("我開始爬取{}網頁了".format(self.name))
time.sleep(2)
print("網頁爬取完成")
class getdetaiurl(threading.thread):
def __init__(self, name):
super().__init__(name = name)
def run(self):
print("我開始爬取{}url".format(self.name))
time.sleep(4)
print("url爬取完成")
if __name__ == "__main__":
thread2 = getdetaiurl("貼吧")
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("執行完成")
執行緒間通訊的兩種方式:
共享變數
queue
import time
import threading
detail_url_list = # 共享變數
def get_detail_html(detail_url_list):
# 爬取文章詳情頁
while true:
if len(detail_url_list):
url = detail_url_list.pop() # pop() 函式用於移除列表中的乙個元素(預設最後乙個元素),並且返回該元素的值。
print('我開始獲取http:/中的詳情'.format(url = url))
time.sleep(2)
print('http:/中的詳情爬取完成'.format(url = url))
def get_detail_url(detail_url_list):
# 爬取文章列表
while true:
print('開始獲取文章url')
time.sleep(4)
for i in range(20):
print('獲取文章url結束')
if __name__ == "__main__":
thread1 = threading.thread(target=get_detail_html, args=detail_url_list)
thread2 = threading.thread(target=get_detail_url, args=detail_url_list)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print('網頁爬取完成')
import time
from queue import queue
import threading
def get_detail_html(queuq):
# 爬取文章詳情頁
while true:
url = queuq.get() # pop() 函式用於移除列表中的乙個元素(預設最後乙個元素),並且返回該元素的值。
print('我開始獲取http:/中的詳情'.format(url = url))
time.sleep(2)
print('http:/中的詳情爬取完成'.format(url = url))
def get_detail_url(queue):
# 爬取文章列表
while true:
print('開始獲取文章url')
time.sleep(4)
for i in range(20):
queue.put(i)
print('獲取文章url結束')
if __name__ == "__main__":
detail_url_queue = queue(maxsize=1000)
thread1 = threading.thread(target=get_detail_html, args=(detail_url_queue, ))
for i in range(10):
thread2 = threading.thread(target=get_detail_url, args=(detail_url_queue, ))
thread2.start()
thread1.start()
# 這兩個命令是成對出現的
# q.task_done(),每次從queue中get乙個資料之後,當處理好相關問題,最後呼叫該方法,以提示q.join()是否停止阻塞,讓執行緒向前執行或者退出;
# q.join(),阻塞,直到queue中的資料均被刪除或者處理。為佇列中的每一項都呼叫一次。
detail_url_queue.task_done()
detail_url_queue.join()
print('網頁爬取完成')
'''
多執行緒操作全域性變數 使用互斥鎖
重點:宣告乙個全域性互斥鎖
1.用鎖會影響效能
2.鎖會引起死鎖
3.'''
import threading
import time
counter = 0
mutex = threading.lock()
class mythread(threading.thread):
def __init__(self):
threading.thread.__init__(self)
def run(self):
global counter, mutex
time.sleep(1);
if mutex.acquire():
counter += 1
print "i am %s, set counter:%s" % (self.name, counter)
mutex.release()
if __name__ == "__main__":
for i in range(0, 100):
my_thread = mythread()
my_thread.start()
'''
在乙個執行緒裡面,可以連續呼叫多次acquire
一定要注意acquire的次數和release次數一樣
'''
多執行緒 多程序?
這幾天在思考如何改進原型在多個客戶端的情況下的效能,特地溫習了一下多程序和多執行緒的一些知識。在linux下程序的程序和執行緒在核心看來區別很小,都是乙個可排程單元,都擁有記憶體管理結構等等。但是關鍵的差別是程序的資源都是私有的,而執行緒則是和別人共享的,所以執行緒的上下文切換可能比程序的開銷要小很...
多程序,多執行緒
多工程式設計 通過應用程式利用多個計算機核心達到多工同時執行的 目的,從此來提公升程式執行效率 多程序,多執行緒 程序 程式在計算機中一次執行的過程 程式 靜態的描述,不占有計算機資源 程序 是乙個動態的過程,占有cpu,記憶體等計算機資源 有一定的生命週期 同乙個程式,每次執行都是不同的程序,因為...
多執行緒 多程序
是什麼?能幹什麼?單執行緒情況下,執行效率低。系統的資源沒有得到充分利用。計算密集型 運算量比較大 io密集型 cpu空閒,輸入輸出較多 怎麼幹?爬蟲 io密集型 多執行緒 橫向 所有的程式的執行都在乙個執行緒中,程式啟動時,啟動多執行緒,每個執行緒跑同樣的 縱向 將程式進行拆分,每個執行緒跑特定的...