1. 程式人生 > >莫煩python之python多執行緒

莫煩python之python多執行緒

地址:https://morvanzhou.github.io/tutorials/python-basic/threading/1-why/

多執行緒
一、新增執行緒
    import threading
    import time
    def thread_job():
            print("T1 start\n")
            for i in range(10):
                time.sleep(0.1)  # 任務間隔0.1s
            print("T1 finish\n")

    def main():
            added_thread = threading.Thread(target=thread_job, name='T1')
            added_thread.start()
            print("all done\n")

    if __name__ == '__main__':  # 如果模組是被直接執行的,則程式碼塊被執行,如果模組是被匯入的,則程式碼塊不被執行。
            main()

    執行結果:    T1 start
            all done
            T1 finish

二、join功能
    在上面例子基礎上修改
    def main():
            added_thread = threading.Thread(target=thread_job, name='T1')
            added_thread.start()
            added_thread.join()    #等待該執行緒執行完才執行後面語句
            print("all done\n")

三、queue:執行緒無法返回值,把結果放到一個佇列,主執行緒中取到
    def job(l,q):
        for i in range(len(l)):
            l[i] = l[i]**2
        q.put(l)        #結果放到一個佇列

    def multithreading():
            q = Queue()
            threads = []
            data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]
            for i in range(4):                #建立四個執行緒,每個執行緒一個小佇列
                t = threading.Thread(target=job,args=(data[i],q))
                t.start()
                threads.append(t)
            for thread in threads:                #所有執行緒運算完畢繼續後面
                    thread.join()
            results = []
            for _ in range(4):                #把結果放到results中列印
                results.append(q.get())
            print(results)
    if __name__ == '__main__':  
            multithreading()

四、GIL(Global Interpreter Lock )不一定有效率,純運算速度沒有提升太高
    測試:
    import threading
    from queue import Queue
    import copy
    import time

    def job(l, q):
            res = sum(l)
            q.put(res)

    def multithreading(l):
            q = Queue()
            threads = []
            for i in range(4):
                t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)
                t.start()
                threads.append(t)
            [t.join() for t in threads]
            total = 0
            for _ in range(4):
                total += q.get()
            print(total)

        def normal(l):
            total = sum(l)
            print(total)

    if __name__ == '__main__':
            l = list(range(1000000))
            s_t = time.time()
            normal(l*4)
            print('normal: ',time.time()-s_t)
            s_t = time.time()
            multithreading(l)
            print('multithreading: ', time.time()-s_t)
    運算結果
    1999998000000
    normal:  0.29871177673339844
    1999998000000
    multithreading:  0.2837047576904297
    使用了多執行緒但是對於純運算速度沒有提升太高,同一時刻只有一個核在運算
    後面會用到多核的運算

五、執行緒鎖:為了讓A完成後在處理B
    import threading

    def job1():
            global A
            for i in range(10):
                A+=1
                print('job1',A)


    def job2():
            global A
            for i in range(10):
                    A+=10
                print('job2',A)



    if __name__== '__main__':
            A=0
            t1=threading.Thread(target=job1)
            t2=threading.Thread(target=job2)
            t1.start()
            t2.start()
            t1.join()
            t2.join()
    不知道為什麼我不用lock也沒有衝突