(更新時間)2021年3月28日 python基礎(chǔ)知識(線程的使用)

      網(wǎng)友投稿 617 2025-04-01

      一. 線程的使用


      1. 導(dǎo)入線程模塊

      #導(dǎo)入線程模塊 import threading

      1

      2

      2. 線程類Thread參數(shù)說明

      Thread([group [, target [, name [, args [, kwargs]]]]])

      group: 線程組,目前只能使用None

      target: 執(zhí)行的目標(biāo)任務(wù)名

      args: 以元組的方式給執(zhí)行任務(wù)傳參

      kwargs: 以字典方式給執(zhí)行任務(wù)傳參

      name: 線程名,一般不用設(shè)置

      3. 啟動線程

      啟動線程使用start方法

      4. 多線程完成多任務(wù)的代碼

      import threading import time # 唱歌任務(wù) def sing(): # 擴(kuò)展: 獲取當(dāng)前線程 # print("sing當(dāng)前執(zhí)行的線程為:", threading.current_thread()) for i in range(3): print("正在唱歌...%d" % i) time.sleep(1) # 跳舞任務(wù) def dance(): # 擴(kuò)展: 獲取當(dāng)前線程 # print("dance當(dāng)前執(zhí)行的線程為:", threading.current_thread()) for i in range(3): print("正在跳舞...%d" % i) time.sleep(1) if __name__ == '__main__': # 擴(kuò)展: 獲取當(dāng)前線程 # print("當(dāng)前執(zhí)行的線程為:", threading.current_thread()) # 創(chuàng)建唱歌的線程 # target: 線程執(zhí)行的函數(shù)名 sing_thread = threading.Thread(target=sing) # 創(chuàng)建跳舞的線程 dance_thread = threading.Thread(target=dance) # 開啟線程 sing_thread.start() dance_thread.start()

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      5. 小結(jié)

      導(dǎo)入線程模塊

      import threading

      1

      創(chuàng)建子線程并指定執(zhí)行的任務(wù)

      sub_thread = threading.Thread(target=任務(wù)名)

      1

      啟動線程執(zhí)行任務(wù)

      sub_thread.start()

      1

      二. 線程執(zhí)行帶有參數(shù)的任務(wù)

      1. 線程執(zhí)行帶有參數(shù)的任務(wù)的介紹

      前面我們使用線程執(zhí)行的任務(wù)是沒有參數(shù)的,假如我們使用線程執(zhí)行的任務(wù)帶有參數(shù),如何給函數(shù)傳參呢?

      Thread類執(zhí)行任務(wù)并給任務(wù)傳參數(shù)有兩種方式:

      args 表示以元組的方式給執(zhí)行任務(wù)傳參

      kwargs 表示以字典方式給執(zhí)行任務(wù)傳參

      2. args參數(shù)的使用

      示例代碼:

      import threading import time # 帶有參數(shù)的任務(wù) def task(count): for i in range(count): print("任務(wù)執(zhí)行中..") time.sleep(0.2) else: print("任務(wù)執(zhí)行完成") if __name__ == '__main__': # 創(chuàng)建子線程 # args: 以元組的方式給任務(wù)傳入?yún)?shù) sub_thread = threading.Thread(target=task, args=(5,)) sub_thread.start()

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      3. kwargs參數(shù)的使用

      示例代碼:

      mport threading import time # 帶有參數(shù)的任務(wù) def task(count): for i in range(count): print("任務(wù)執(zhí)行中..") time.sleep(0.2) else: print("任務(wù)執(zhí)行完成") if __name__ == '__main__': # 創(chuàng)建子線程 # kwargs: 表示以字典方式傳入?yún)?shù) sub_thread = threading.Thread(target=task, kwargs={"count": 3}) sub_thread.start()

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      4. 小結(jié)

      線程執(zhí)行任務(wù)并傳參有兩種方式:

      元組方式傳參(args) :元組方式傳參一定要和參數(shù)的順序保持一致。

      字典方式傳參(kwargs):字典方式傳參字典中的key一定要和參數(shù)名保持一致。

      四. 線程使用的相關(guān)注意點(diǎn)

      1. 線程的注意點(diǎn)介紹

      線程之間執(zhí)行是無序的

      主線程會等待所有的子線程執(zhí)行結(jié)束再結(jié)束

      線程之間共享全局變量

      線程之間共享全局變量數(shù)據(jù)出現(xiàn)錯誤問題

      2. 線程之間執(zhí)行是無序的

      import threading import time def task(): time.sleep(1) print("當(dāng)前線程:", threading.current_thread().name) if __name__ == '__main__': for _ in range(5): sub_thread = threading.Thread(target=task) sub_thread.start()

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      說明:

      線程之間執(zhí)行是無序的,它是由cpu調(diào)度決定的 ,cpu調(diào)度哪個線程,哪個線程就先執(zhí)行,沒有調(diào)度的線程不能執(zhí)行。

      進(jìn)程之間執(zhí)行也是無序的,它是由操作系統(tǒng)調(diào)度決定的,操作系統(tǒng)調(diào)度哪個進(jìn)程,哪個進(jìn)程就先執(zhí)行,沒有調(diào)度的進(jìn)程不能執(zhí)行。

      3. 主線程會等待所有的子線程執(zhí)行結(jié)束再結(jié)束

      假如我們現(xiàn)在創(chuàng)建一個子線程,這個子線程執(zhí)行完大概需要2.5秒鐘,現(xiàn)在讓主線程執(zhí)行1秒鐘就退出程序,查看一下執(zhí)行結(jié)果,示例代碼如下:

      import threading import time # 測試主線程是否會等待子線程執(zhí)行完成以后程序再退出 def show_info(): for i in range(5): print("test:", i) time.sleep(0.5) if __name__ == '__main__': sub_thread = threading.Thread(target=show_info) sub_thread.start() # 主線程延時1秒 time.sleep(1) print("over")

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      設(shè)置守護(hù)主線程的示例代碼:

      import threading import time # 測試主線程是否會等待子線程執(zhí)行完成以后程序再退出 def show_info(): for i in range(5): print("test:", i) time.sleep(0.5) if __name__ == '__main__': # 創(chuàng)建子線程守護(hù)主線程 # daemon=True 守護(hù)主線程 # 守護(hù)主線程方式1 sub_thread = threading.Thread(target=show_info, daemon=True) # 設(shè)置成為守護(hù)主線程,主線程退出后子線程直接銷毀不再執(zhí)行子線程的代碼 # 守護(hù)主線程方式2 # sub_thread.setDaemon(True) sub_thread.start() # 主線程延時1秒 time.sleep(1) print("over")

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      3. 線程之間共享全局變量

      需求:

      定義一個列表類型的全局變量

      創(chuàng)建兩個子線程分別執(zhí)行向全局變量添加數(shù)據(jù)的任務(wù)和向全局變量讀取數(shù)據(jù)的任務(wù)

      查看線程之間是否共享全局變量數(shù)據(jù)

      import threading import time # 定義全局變量 my_list = list() # 寫入數(shù)據(jù)任務(wù) def write_data(): for i in range(5): my_list.append(i) time.sleep(0.1) print("write_data:", my_list) # 讀取數(shù)據(jù)任務(wù) def read_data(): print("read_data:", my_list) if __name__ == '__main__': # 創(chuàng)建寫入數(shù)據(jù)的線程 write_thread = threading.Thread(target=write_data) # 創(chuàng)建讀取數(shù)據(jù)的線程 read_thread = threading.Thread(target=read_data) write_thread.start() # 延時 # time.sleep(1) # 主線程等待寫入線程執(zhí)行完成以后代碼在繼續(xù)往下執(zhí)行 write_thread.join() print("開始讀取數(shù)據(jù)啦") read_thread.start()

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      4. 線程之間共享全局變量數(shù)據(jù)出現(xiàn)錯誤問題

      需求:

      定義兩個函數(shù),實(shí)現(xiàn)循環(huán)100萬次,每循環(huán)一次給全局變量加1

      創(chuàng)建兩個子線程執(zhí)行對應(yīng)的兩個函數(shù),查看計算后的結(jié)果

      import threading # 定義全局變量 g_num = 0 # 循環(huán)一次給全局變量加1 def sum_num1(): for i in range(1000000): global g_num g_num += 1 print("sum1:", g_num) # 循環(huán)一次給全局變量加1 def sum_num2(): for i in range(1000000): global g_num g_num += 1 print("sum2:", g_num) if __name__ == '__main__': # 創(chuàng)建兩個線程 first_thread = threading.Thread(target=sum_num1) second_thread = threading.Thread(target=sum_num2) # 啟動線程 first_thread.start() # 啟動線程 second_thread.start()

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      (更新時間)2021年3月28日 python基礎(chǔ)知識(線程的使用)

      26

      27

      28

      29

      30

      31

      32

      注意點(diǎn):

      多線程同時對全局變量操作數(shù)據(jù)發(fā)生了錯誤

      錯誤分析:

      兩個線程first_thread和second_thread都要對全局變量g_num(默認(rèn)是0)進(jìn)行加1運(yùn)算,但是由于是多線程同時操作,有可能出現(xiàn)下面情況:

      在g_num=0時,first_thread取得g_num=0。此時系統(tǒng)把first_thread調(diào)度為”sleeping”狀態(tài),把second_thread轉(zhuǎn)換為”running”狀態(tài),t2也獲得g_num=0

      然后second_thread對得到的值進(jìn)行加1并賦給g_num,使得g_num=1

      然后系統(tǒng)又把second_thread調(diào)度為”sleeping”,把first_thread轉(zhuǎn)為”running”。線程t1又把它之前得到的0加1后賦值給g_num。

      這樣導(dǎo)致雖然first_thread和first_thread都對g_num加1,但結(jié)果仍然是g_num=1

      全局變量數(shù)據(jù)錯誤的解決辦法:

      線程同步: 保證同一時刻只能有一個線程去操作全局變量 同步: 就是協(xié)同步調(diào),按預(yù)定的先后次序進(jìn)行運(yùn)行。如:你說完,我再說, 好比現(xiàn)實(shí)生活中的對講機(jī)

      線程同步的方式:

      線程等待(join)

      互斥鎖

      線程等待的示例代碼:

      import threading # 定義全局變量 g_num = 0 # 循環(huán)1000000次每次給全局變量加1 def sum_num1(): for i in range(1000000): global g_num g_num += 1 print("sum1:", g_num) # 循環(huán)1000000次每次給全局變量加1 def sum_num2(): for i in range(1000000): global g_num g_num += 1 print("sum2:", g_num) if __name__ == '__main__': # 創(chuàng)建兩個線程 first_thread = threading.Thread(target=sum_num1) second_thread = threading.Thread(target=sum_num2) # 啟動線程 first_thread.start() # 主線程等待第一個線程執(zhí)行完成以后代碼再繼續(xù)執(zhí)行,讓其執(zhí)行第二個線程 # 線程同步: 一個任務(wù)執(zhí)行完成以后另外一個任務(wù)才能執(zhí)行,同一個時刻只有一個任務(wù)在執(zhí)行 first_thread.join() # 啟動線程 second_thread.start()

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      5. 小結(jié)

      線程執(zhí)行執(zhí)行是無序的

      主線程默認(rèn)會等待所有子線程執(zhí)行結(jié)束再結(jié)束,設(shè)置守護(hù)主線程的目的是主線程退出子線程銷毀。

      線程之間共享全局變量,好處是可以對全局變量的數(shù)據(jù)進(jìn)行共享。

      線程之間共享全局變量可能會導(dǎo)致數(shù)據(jù)出現(xiàn)錯誤問題,可以使用線程同步方式來解決這個問題。

      Python 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:excel限制單元格輸入的方法
      下一篇:Excel表格中三維餅圖有哪些制作方法(excel怎么做三維餅圖)
      相關(guān)文章
      亚洲精品mv在线观看| 亚洲午夜福利精品久久| 久久亚洲2019中文字幕| 亚洲成A人片在线观看无码3D| 亚洲国产成人精品无码区二本| 2017亚洲男人天堂一| 亚洲一欧洲中文字幕在线| 91亚洲视频在线观看| 亚洲欧洲自拍拍偷综合| 亚洲伊人色一综合网| 亚洲中字慕日产2021| 亚洲一区二区三区高清不卡| www.亚洲成在线| 亚洲乱码一二三四五六区| 亚洲理论片中文字幕电影| 亚洲首页在线观看| 亚洲福利一区二区精品秒拍| 亚洲国产成人综合| 国产精品亚洲综合五月天| 亚洲中文字幕乱码熟女在线| 人人狠狠综合久久亚洲婷婷| 亚洲人JIZZ日本人| 亚洲精品白浆高清久久久久久| 国产AV无码专区亚洲Av| 亚洲国产成人久久综合一| 亚洲综合精品一二三区在线| 亚洲av手机在线观看| 亚洲爆乳大丰满无码专区| 亚洲av无码成人精品区一本二本 | 亚洲AV永久无码精品| 亚洲人成影院在线| 亚洲妓女综合网99| 亚洲一卡2卡3卡4卡5卡6卡| 亚洲欧洲视频在线观看| 亚洲一级毛片在线播放| 中文字幕无码亚洲欧洲日韩| 亚洲国产成人AV网站| 亚洲七七久久精品中文国产| 亚洲乱码在线观看| 亚洲人成色在线观看| 亚洲色无码国产精品网站可下载|