1. 程式人生 > >多工版——執行緒

多工版——執行緒

併發和並行

併發:指的是指的是任務數多於cpu的核數,通過作業系統的排程,實現多個任務一起執行,是一種偽裝的一起執行,實際上是在各個人物之間快速排程。
並行:指的是任務數小於cpu的核數,任務是真的一起執行。

執行緒

執行緒指的是在程式的執行過程中,執行程式程式碼的一個分支,每個執行的程式至少有一個執行緒(主執行緒)。

多執行緒執行任務的程式碼

#匯入執行緒模組
import threading
import time


#定義一個唱歌的任務
def sing(sum):
	for i in range(sum):
		print('正在唱歌。。。%d' % i)
	time.sleep(1)

#定義一個跳舞的方法
def dance(sum):
	for i in range(sum):
		print('正在跳舞。。。%d' % i)
	time.sleep(1)

if __name__ == '__main__':
	#建立唱歌的執行緒
	sing_thread = threading.Thread(target=sing,args=(3,))
	#建立跳舞的執行緒
	dance_thread = threading.Thread(target=dance,kwargs={'num':3})

#開啟執行緒
sing_thread.start()
dance_thread.start()

補充說明

執行緒類Thread的引數:
group:執行緒組,目前只能使用None。
target:執行的目標任務名。
args:以元組的方式傳參。
kwargs:以字典的方式傳參。
name:執行緒名,一般不設定。
獲取當前執行緒號的方法:threading.current_thread()
獲取當前活動的執行緒列表:threading.enumerate()

執行緒注意點:

 1.執行緒之間的執行是無序的。
 2.主執行緒會等待所有的子執行緒執行結束之後才結束。
 3.守護主執行緒:就是指主執行緒退出之後,子執行緒直接銷燬,不會繼續執行子執行緒程式碼。
 	守護主執行緒方式1:
		設定執行緒的時候,在指定目標任務名後,新增引數daemon=True
	守護主執行緒方式2:
		執行緒名.setDaemon=True
 4.執行緒之間是共享全域性變數的。

自定義執行緒

import threading

# 自定義執行緒類
class MyThread(threading.Thread):
    # 通過構造方法取接收任務的引數
    def __init__(self, info1, info2):
        # 呼叫父類的構造方法
        super(MyThread, self).__init__()
        self.info1 = info1
        self.info2 = info2

    # 定義自定義執行緒相關的任務
    def test1(self):
        print(self.info1)

    def test2(self):
        print(self.info2)

    # 通過run方法執行相關任務
    def run(self):
        self.test1()
        self.test2()

# 建立自定義執行緒
my_thread = MyThread("測試1", "測試2")
# 啟動
my_thread.start()
#在自定義執行緒中不能指定target方法,因為自定義執行緒裡面的任務都是在run方法中執行。
啟動執行緒同一使用start方法,不能呼叫類中定義的run方法,因為run呼叫啟動會導致執行緒在主執行緒中執行的。

執行緒共享全域性變數的問題

執行緒之間由於是共享全域性變數,但是當多個執行緒同時操作全域性變數,那麼會導致出現問題。因此我們就需要保證在一個時刻只能有一個執行緒是使用並操作這個全域性變數。

執行緒同步

1.執行緒等待(主執行緒會等待第一個執行緒執行結束之後,再執行接下來的程式碼或者接下來的執行緒,從而保證只有一個執行緒在執行)
	執行緒名.join()
2.互斥鎖(對共享的資料進行鎖定,搶到鎖的行程才能夠去操作這個變數)
	threading模組中定義了Lock變數,本質是一個函式,可以方便進行處理鎖定。
	# 建立鎖
	mutex = threading.Lock()
	# 鎖定
	mutex.acquire()
	# 釋放
	mutex.release()
3.死鎖(就是指沒有在合適的地方釋放鎖,導致程式無法進行下去)