Python多任務(2.線程(創建線程的兩種方式))

Python中threading模塊

可以總結出:   

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

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

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

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

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

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

下面看例子:

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

      單線程執行

import time

def eat_fish():
    print("--正在吃魚--")
    time.sleep(1)

if __name__ == '__main__':
    for i in range(5):
        eat_fish()
        
'''
運行的結果,  一次只執行一次,5秒鐘執行完成
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
'''

    多線程執行

t =  threading.Thread(target=函數名)   # 生成一個子線程對象

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

import threading
import time

def eat_candy():
    print("--正在吃糖果--")
    time.sleep(1)

if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target=eat_candy)  # 給target傳入函數的名字
        # 生成一個實例對象 t 
        t.start()   # 啓動線程,即讓線程開始執行

'''
運行的結果,  一次就執行完成,花費1秒執行完成
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
'''

2. 查看線程數  

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

   (1) 循環查看當前運行的線程

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:
        print(threading.enumerate())  # 打印出線程的列表
        '''所有的線程只剩一個的時候(即主線程)就退出'''
        if len(threading.enumerate())<=1:
            break
        time.sleep(1)
if __name__ == '__main__':
    main()

 Thread執行的函數結束時,線程就結束了,所以打印線程的長度是就會少一個。

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

import threading
import time


def test1():
    for i in range(5):
        print("----test1---%d---" % i)
        time.sleep(1)


def main():
    # 在調用Thread之前先打印當前線程信息
    print(threading.enumerate())
    t1 = threading.Thread(target=test1)

    # 在調用Thread之後打印
    print(threading.enumerate())

    t1.start()

    # 在調用start()之後打印
    print(threading.enumerate())


if __name__ == '__main__':
    main()

 結果:  

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

   (1)  適合一個線程裏面做的事情比較複雜,而且分了多個函數來做,一般來封裝成一個類,

              類裏面覆寫run()方法

              用這個類的實例對象來調用start()方法

    (2)如果類裏面還有其他的方法想要用子線程,
             直接在run()方法裏面調用就行(例如:self.login())
             如果直接用實例.方法名時,不會創建子線程

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg = "I'm"+self.name+"@"+str(i) # name 屬性中保存的是當前線程的名字
            print(msg)


    def login(self):
        pass
    '''
        如果類裏面還有其他的方法想要用子線程,
        直接在run()方法裏面調用就行(例如:self.login())
        如果直接用實例.方法名時,不會創建子線程,
    '''

if __name__ == '__main__':
    t = MyThread()
    t.start()    # 直接利用類的實例對象調用start()方法

運行結果:  

I'mThread-1@0
I'mThread-1@1
I'mThread-1@2

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