python多線程工作原理與實現代碼演示

1.什麼叫多任務?

        什麼叫“多任務”呢?簡單地說,就是操作系統可以同時運行多個任務。打個比方,你一邊在用瀏覽器上網,一邊在聽MP3,一邊在用Word趕作業,這就是多任務,至少同時有3個任務正在運行。還有很多任務悄悄地在後臺同時運行着,只是桌面上沒有顯示而已。

2.設麼叫線程與進程?

1.進程與線程的描述

進程:是指在系統中正在運行的一個應用程序;
線程:是系統分配處理器時間資源的基本單元(系統內程序執行的最小單元),或者說進程之內獨立執行的一個單元。對於操作系統而言,其調度單元是線程。可以理解成一個或多個線程組成了一個進程
2.案例說明
比如在線看視頻 其實是 一邊從網上下載 一邊用播放器播放,從進程來講就一個(咱們打開的網頁) , 其中下載由一個線程管理,播放由一個線程管理.所以這裏一個進程有多個線程管理運行的。

3.多任務和多線程,進程之間的關係

  1. 多任務可以由多進程完成,也可以由一個進程內的多線程完成
  2. 進程是由若干線程組成的,一個進程至少有一個線程。

3.python中線程的實現

python中使用threading模塊下的Thread類實現線程的應有。

3.1.單線程執行一個程序

#coding=utf-8
import time

def start_Demo1():
    print("i am demo1 .....")
    time.sleep(3)
    print("start_Demo1()單次執行結束")

def start_Demo2():
    print("i am demo2")
    time.sleep(1)
    print("start_Demo2()單次執行結束")

if __name__ == "__main__":
    for i in range(3):
        print("第%d次循環開始:"%(i+1)+time.ctime())
        start_Demo1()
        start_Demo2()
        print("第%d次循環結束:" % (i + 1) + time.ctime())
'''
第1次循環開始:Wed Jul  3 11:33:45 2019
i am demo1 .....
start_Demo1()單次執行結束
i am demo2
start_Demo2()單次執行結束
第1次循環結束:Wed Jul  3 11:33:49 2019
第2次循環開始:Wed Jul  3 11:33:49 2019
i am demo1 .....
start_Demo1()單次執行結束
i am demo2
start_Demo2()單次執行結束
第2次循環結束:Wed Jul  3 11:33:53 2019
第3次循環開始:Wed Jul  3 11:33:53 2019
i am demo1 .....
start_Demo1()單次執行結束
i am demo2
start_Demo2()單次執行結束
第3次循環結束:Wed Jul  3 11:33:57 2019
'''

上面可以看出,通過一個主線程(單線程)執行這個程序,可以發現,程序在單次循環內按順序執行,先執行完demo1纔開始執行demo2的,單次循環耗時4s左右。 然後再多次循環執行,程序花費的時間大概在12s左右,輸出有序。

3.2多線程執行同一個程序

import threading
import time

def start_Demo1():
    print("i am demo1 .......")
    time.sleep(3)  #使用多線程併發時,程序不會等待sleep,而是直接執行
    print("start_Demo1()單次執行結束")

def start_Demo2():
    print("i am demo2 .......")
    time.sleep(1)
    print(" start_Demo2()單次執行結束")

if __name__ == "__main__":
    for i in range(3):
        t1 = threading.Thread(target=start_Demo1)
        t2 = threading.Thread(target=start_Demo2)
        print("第%d次循環開始:" % (i + 1) + time.ctime())
        t1.start() #當調用start()時,纔會真正的創建線程,並且開始執行
        t2.start()  # 啓動線程,即讓線程開始執行
        print("第%d次循環結束:" % (i + 1) + time.ctime())

'''
第1次循環開始:Wed Jul  3 11:35:30 2019
i am demo1 .......
i am demo2 .......
第1次循環結束:Wed Jul  3 11:35:30 2019
第2次循環開始:Wed Jul  3 11:35:30 2019
i am demo1 .......
i am demo2 .......
第2次循環結束:Wed Jul  3 11:35:30 2019
第3次循環開始:Wed Jul  3 11:35:30 2019
i am demo1 .......
i am demo2 .......
第3次循環結束:Wed Jul  3 11:35:30 2019
 start_Demo2()單次執行結束
 start_Demo2()單次執行結束
 start_Demo2()單次執行結束
start_Demo1()單次執行結束
start_Demo1()單次執行結束
start_Demo1()單次執行結束
'''

    注意,同一個程序啓動多線程執行後,demo1,demo2啓動多線程後,程序直接執行下去,不會等待sleep,。尤其要注意函數裏的第二個print()打印的時間,是在最後。

3.查看運行中的線程個數

  • threading.enumerate(): 返回一個包含正在運行的線程的list。正在運行指線程啓動後、結束前,不包括啓動前和終止後的線程
import threading
import time

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

def test2():
    for i in range(3):
        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())
        time.sleep(1)

if __name__ == "__main__":
    main()
'''
-----test1---0---
-----test2---0---
[<_MainThread(MainThread, started 10376)>, <Thread(Thread-1, started 6848)>, <Thread(Thread-2, started 7784)>]
-----test2---1---
-----test1---1---
[<_MainThread(MainThread, started 10376)>, <Thread(Thread-1, started 6848)>, <Thread(Thread-2, started 7784)>]
-----test2---2---
[<_MainThread(MainThread, started 10376)>, <Thread(Thread-1, started 6848)>, <Thread(Thread-2, started 7784)>]
-----test1---2---
[<_MainThread(MainThread, started 10376)>, <Thread(Thread-1, started 6848)>, <Thread(Thread-2, started 7784)>]
[<_MainThread(MainThread, started 10376)>]
[<_MainThread(MainThread, started 10376)>]
[<_MainThread(MainThread, started 10376)>]
[<_MainThread(MainThread, started 10376)>]
[<_MainThread(MainThread, started 10376)>]

'''

上面可以看出,t1和t2的具體的執行順序根據 cpu的調度順序決定的,不一定誰在前面就誰先執行,可以看出t1t2在執行過程中有三個線程 ,t1t2結束後接只剩下一個主線程了,如果程序結束後,主線程也會關閉。主線程會等待所有的子線程結束後才結束

4.注意下面兩個多線程程序的執行結果 

1.將循環放在主線程裏,主線程將任務調度給對應子線程執行後,就會直接執行下次主線程循環,而不是等待上一次子線程執行完後才執行下次循環。所以造成第一次循環的子線程還沒執行完,在sleep,子線程又開始執行第二次循環。

#1.循環在主線程裏
import threading
import time

def start_Demo1():
    print("i am demo1 .......")
    time.sleep(3)  #使用多線程併發時,程序不會等待sleep,而是直接執行
    print("start_Demo1()單次執行結束")

def start_Demo2():
    print("i am demo2 .......")
    time.sleep(1)
    print(" start_Demo2()單次執行結束")

if __name__ == "__main__":
    for i in range(3):
        t1 = threading.Thread(target=start_Demo1)
        t2 = threading.Thread(target=start_Demo2)
        print("第%d次循環開始:" % (i + 1) + time.ctime())
        t1.start() #當調用start()時,纔會真正的創建線程,並且開始執行
        t2.start()  # 啓動線程,即讓線程開始執行
        print("第%d次循環結束:" % (i + 1) + time.ctime())
'''
第1次循環開始:Wed Jul  3 14:00:37 2019
i am demo1 .......
i am demo2 .......
第1次循環結束:Wed Jul  3 14:00:37 2019
第2次循環開始:Wed Jul  3 14:00:37 2019
i am demo1 .......
i am demo2 .......
第2次循環結束:Wed Jul  3 14:00:37 2019
第3次循環開始:Wed Jul  3 14:00:37 2019
i am demo1 .......
i am demo2 .......
第3次循環結束:Wed Jul  3 14:00:37 2019
 start_Demo2()單次執行結束
 start_Demo2()單次執行結束
 start_Demo2()單次執行結束
start_Demo1()單次執行結束
start_Demo1()單次執行結束
start_Demo1()單次執行結束
'''

2.將循環放到子線程裏,發現,子線程必須單次執行完(執行sleep,並且執行sleep後的語句後),纔會進行下次循環。 

import  threading
import time

def start_Demo1():
    for i in range(3):
        print("i am demo1 .....")
        time.sleep(3)
        print("start_Demo1()單次執行結束")

def start_Demo2():
    for i in range(3):
        print("i am demo2")
        time.sleep(1)
        print("start_Demo2()單次執行結束")

if __name__ == "__main__":
        t1 = threading.Thread(target=start_Demo1)
        t2 = threading.Thread(target=start_Demo2)
        print("第1次循環開始:"  + time.ctime())
        t1.start()  # 當調用start()時,纔會真正的創建線程,並且開始執行
        t2.start()  # 啓動線程,即讓線程開始執行
        print("第1次循環結束:"  + time.ctime())
'''
第1次循環開始:Wed Jul  3 14:05:36 2019
i am demo1 .....
i am demo2
第1次循環結束:Wed Jul  3 14:05:36 2019
start_Demo2()單次執行結束
i am demo2
start_Demo2()單次執行結束
i am demo2
start_Demo1()單次執行結束
i am demo1 .....
start_Demo2()單次執行結束
start_Demo1()單次執行結束
i am demo1 .....
start_Demo1()單次執行結束
'''

 

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