Python多任務【多線程(兩種創建方式)】

Python的標準庫提供了兩個模塊:_threadthreading_thread是低級模塊,threading是高級模塊,對_thread進行了封裝。絕大多數情況下,我們只需要使用threading這個高級模塊。Python的線程是真正的Posix Thread,而不是模擬出來的線程。

Python中threading模塊

可以總結出:   

(1)當調用Thread的時候,不會創建線程

(2)調用Thread創建出來的實例對象的start方法的時候,纔會創建線程以及讓這個線程開始運行

         線程真正創建是調用start(),線程真正結束是主線程結束

(3)主線程會等待所有的子線程結束後才結束

(4)線程創建後誰先執行是不確定的,要確定先後的順序可以通過延時的方式來保證

(5)只要主線程一死,其他的子線程就會全部結束

1.用threading創建多線程來執行任務

import time
import threading
def sing():
    print("---singing---")
    time.sleep(1)
    print(time.ctime())
if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target = sing)
        t.start()
    

執行結果:1秒執行完畢,5個任務同時執行

t =  threading.Thread(target=函數名)   # 生成一個子線程對象,只生成對象,只有start後纔是真正創建子線程

t.start()                                                  #  然後利用這個對象調用start()方法,,來創建一個子線程

2.在使用Thread時,線程是從什麼時候開始創建的,什麼時候結束

threading.enumerate() # 返回值是一個列表,裏面有當前執行的所有線程 

threading.current_thread()    # 查看線程的名字 

import time
import threading
def sing():
    print("---singing---")
    time.sleep(1)
if __name__ == '__main__':
    #在調用Thread之前打印線程
    print(threading.enumerate())
    t = threading.Thread(target = sing)
    #在調用Thread之後打印線程
    print(threading.enumerate())
    #在調用start之後打印線程
    t.start()
    print(threading.enumerate())

 運行結果:

從結果可以看出線程真正被創建是在start執行之後,在只創建子線程對象時並沒有創建線程。

3. 子線程是在創建Thread時執行的函數運行結束後結束    

import threading
import time
def test1():
    for i in range(3):
        print("----test1---%d---" % i)
        time.sleep(1)
    '''如果創建Thread時執行的函數運行結束,那麼意味着 這個子線程就結束了'''
def test2():
    for i in range(6):
        print("----test2---%d---" % i)
        time.sleep(1)
def main():
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)
    t1.start()
    t2.start()
    while True:
        #time.sleep(1)
        print(threading.enumerate())  # 打印出線程的列表
        '''所有的線程只剩一個的時候(即主線程)就退出'''
        if len(threading.enumerate()) <= 1:
            break
        time.sleep(1)
if __name__ == '__main__':
    main()

 

從結果可以分析出t1子線程是在執行三次test1函數後結束,t2子線程是在執行六次test2之後結束,不明白爲什麼在運行結果中存在了七次。

可得出:如果創建Thread時執行的函數運行結束,那麼意味着這個子線程就結束了。

#疑問1:t2子線程是在執行六次test2之後結束,不明白爲什麼在運行結果中存在了七次。

#疑問2:爲什麼在打印線程時總是很亂的順序,比如多行打印在一行;每次打印結果順序都不一樣;

4.通過繼承Thread類完成創建線程

類裏面覆寫run()方法,用這個類的實例對象來調用start()方法

import threading
import time
class MyThread(threading.Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            print(self.name)
    def login(self):
        pass
    '''
        如果類裏面還有其他的方法想要用子線程,
        直接在run()方法裏面調用就行(例如:self.login())
        如果直接用實例.方法名時,不會創建子線程,
    '''
if __name__ == '__main__':
    t = MyThread()
    t.start()  # 直接利用類的實例對象調用start()方法

5.利用threading創建線程時傳入參數--args參數

args傳遞參數,參數指定的一定是一個元組類型

t = threading.Thread(target = 函數名,args = (1,2,) )

 

import time
import threading
def sing(name):
    print(time.ctime() + ' ' + name + " is singing!")
    time.sleep(1)
if __name__ == '__main__':
    names = ['YaoMing','Curry','Kobe','Durant','Jordan']
    for i in range(5):
        t = threading.Thread(target = sing,args = (names[i],))
        t.start()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章