1. 程式人生 > >【python學習筆記】第8天

【python學習筆記】第8天

繼續今天的python學習

昨天我們說到了多執行緒共享資料(全域性變數),那麼今天我們就緊接著來說一下多執行緒不共享資料的使用方式

import threading
import time
def test1():
    the_number = 0
    for i in range(100):
        the_number += 1
    time.sleep(1)
    print(threading.current_thread().name + "the_number = %d"%(the_number))

def test2():
    the_number = 0;
    for i in range(200):
        the_number += 1
    time.sleep(2)
    print(threading.current_thread().name + "the_number = %d"%(the_number))

t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()

執行結果:

Thread-1the_number = 100
Thread-2the_number = 200

可以看到兩個執行緒之間是互不影響的。

然後提到了一個死鎖的問題,看如下程式碼:  

import threading


class Thread1(threading.Thread):
    def run(self):
        if mutexA.acquire():
            print("mutexA doing in 1")
            if mutexB.acquire():
                print("mutexB doing in 1")
                mutexB.release()
            mutexA.release()

class Thread2(threading.Thread):
    def run(self):
        if mutexB.acquire():
            print("mutexB doing in 2")
            if mutexA.acquire():
                print("mutexA doing in 2")
                mutexA.release()
            mutexB.release()

mutexA = threading.Lock()
mutexB = threading.Lock()

if __name__ == "__main__":
    t1 = Thread1()
    t2 = Thread2()
    t1.start()
    t2.start()

首先兩個執行緒對mutexA和mutexB進行了上鎖,而後線上程內部有企圖去搶對方的鎖,但是之前的mutexA和mutexB已經被使用,所以兩個執行緒不能再使用,於是程式就卡在了這裡沒辦法繼續,這樣就是死鎖的一種情況。

執行結果:

第一種:
mutexA doing in 1
mutexB doing in 1
mutexB doing in 2
mutexA doing in 2
-------------------
第二種:
mutexA doing in 1
mutexB doing in 2

第一種並沒有被鎖死,那麼原因是什麼呢?

我想應該是線上程執行時產生的時間差導致的,因為程式執行很快嘛。。。

第二種就是出現死鎖的情況了,然後程式一直會卡在這裡,這樣很危險,也會造成相當大的損失,所以在寫程式的時候一定要避免死鎖!!!

如何避免死鎖的,課上提到了一種銀行家演算法,由於課上沒有實現,今天暫且不談,後續我會更新這個演算法的細節。

接下來談到的是一個非同步的問題,首先,什麼是非同步呢,就是沒有規定的不掉,程式誰先執行不一定,那麼同步就是按照規定好的順序去執行程式碼:

import threading
import time

def work1():
    while True:
        if lock1.acquire():
            print("----1----")
            lock2.release()
def work2():
    while True:
        if lock2.acquire():
            print("----2----")
            lock3.release()

def work3():
    while True:
        if lock3.acquire():
            print("----3----")
            time.sleep(1)
            lock1.release()



lock1 = threading.Lock()

lock2 = threading.Lock()
lock2.acquire()
lock3 = threading.Lock()
lock3.acquire()

t1 = threading.Thread(target=work1)
t2 = threading.Thread(target=work2)
t3 = threading.Thread(target=work3)
t1.start()
t2.start()
t3.start()

執行結果:

----1----
----2----
----3----
----1----
----2----
----3----
----1----
----2----
----3----
----1----
----2----
----3----
----1----
----2----
----3----

可以看出來是按1,2,3的先後順序來執行的,這就是同步

接著是耦合的問題,什麼是耦合?老師課上舉了一個例子,一個人做包子,一個人吃包子,吃包子的速度可能與做包子的速度不相同,那麼這樣就會產生一些問題,那麼在程式中也一樣,再執行爬蟲時爬資料的速度和處理資料的速度不匹配會導致一些時間唄浪費,那麼為了解決這樣的問題,我們用到了queue模組中的Queue(佇列)。