1.什麼叫多任務?
什麼叫“多任務”呢?簡單地說,就是操作系統可以同時運行多個任務。打個比方,你一邊在用瀏覽器上網,一邊在聽MP3,一邊在用Word趕作業,這就是多任務,至少同時有3個任務正在運行。還有很多任務悄悄地在後臺同時運行着,只是桌面上沒有顯示而已。
2.設麼叫線程與進程?
1.進程與線程的描述
進程:是指在系統中正在運行的一個應用程序;
線程:是系統分配處理器時間資源的基本單元(系統內程序執行的最小單元),或者說進程之內獨立執行的一個單元。對於操作系統而言,其調度單元是線程。可以理解成一個或多個線程組成了一個進程
2.案例說明
比如在線看視頻 其實是 一邊從網上下載 一邊用播放器播放,從進程來講就一個(咱們打開的網頁) , 其中下載由一個線程管理,播放由一個線程管理.所以這裏一個進程有多個線程管理運行的。
3.多任務和多線程,進程之間的關係
- 多任務可以由多進程完成,也可以由一個進程內的多線程完成
- 進程是由若干線程組成的,一個進程至少有一個線程。
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()單次執行結束
'''