手把手教你做項(xiàng)目多線程篇——基礎(chǔ)知識(shí)詳解

      網(wǎng)友投稿 758 2025-03-31

      項(xiàng)目中多線程的目的

      具體原理我覺得這應(yīng)該是可以跳到操作系統(tǒng)里面了一點(diǎn)點(diǎn)小小總結(jié)大家還可以找本操作系統(tǒng)的書看看,老規(guī)矩找不到的話找我主頁(yè),有一個(gè)關(guān)于資源的文章里面有資源當(dāng)然也可以私信我。

      我們?cè)僬f說我們項(xiàng)目里面用多線程的目的:

      1.線程之間共享內(nèi)存非常容易。

      2·使用多線程來實(shí)現(xiàn)多任務(wù)并發(fā)執(zhí)行比使用多進(jìn)程的效率高

      3·有時(shí)候可以節(jié)省運(yùn)行時(shí)間,這個(gè)一會(huì)在下面就會(huì)知道

      4·當(dāng)你一個(gè)文件要同時(shí)執(zhí)行多個(gè)功能時(shí)就可以用到多線程

      手把手教你做項(xiàng)目多線程篇——基礎(chǔ)知識(shí)詳解

      python語(yǔ)言內(nèi)置了多線程功能支持,而不是單純地作為底層操作系統(tǒng)的調(diào)度方式,從而簡(jiǎn)化了python的多線程編程。

      實(shí)戰(zhàn)操作

      說這么多不如實(shí)際動(dòng)手練練,首先導(dǎo)入線程

      特別注意:

      大家在見建文件的時(shí)候名字千萬(wàn)別和導(dǎo)入的包threading一樣不然會(huì)出錯(cuò)的。

      小知識(shí)

      import threading

      讓我們先看看自己程序現(xiàn)在有多少個(gè)進(jìn)程

      import threading def main(): print(threading.current_thread()) if __name__ == '__main__': main()

      結(jié)果:1#我的就一個(gè)你的呢?

      如果你的進(jìn)程不為一的話還可以這樣查看每一個(gè)進(jìn)程名

      import threading def main(): print(threading.active_count()) print(threading.enumerate()) if __name__ == '__main__': main()

      >>>[<_MainThread(MainThread, started 36004)>]#返回的是一個(gè)列表因?yàn)槲业哪壳熬鸵粋€(gè)所以就一個(gè)主進(jìn)程

      還可以查看正在運(yùn)行的進(jìn)程

      import threading def main(): print(threading.active_count()) print(threading.enumerate()) print(threading.current_thread()) if __name__ == '__main__': main()

      >1 [<_MainThread(MainThread, started 36004)>] <_MainThread(MainThread, started 36004)>

      創(chuàng)建一個(gè)簡(jiǎn)單的線程

      首先我們先介紹一下threading.Thread()里面的參數(shù),大家學(xué)python每個(gè)模塊的功能時(shí)最好還是看一下源文件內(nèi)容,這樣有助于提高你的編程能力:

      需要注意的點(diǎn)我已經(jīng)打上標(biāo)記了

      import threading def first(): print("frist active") print("frist finish") def main(): first_thread=threading.Thread(target=first,name="T1") first_thread.start()#開始的標(biāo)志 print("main") if __name__ == '__main__': main()

      結(jié)果: 第一次運(yùn)行 frist active main frist finish 第二次運(yùn)行 frist active frist finish main

      每次的結(jié)果不一樣就已經(jīng)表明Frist和main是同時(shí)運(yùn)行的了。

      如果說效果不太明顯的話,我們改進(jìn)一下接下來我們引入

      import time

      import threading import time def first(): print("frist active") time.sleep(3) print("frist finish") def main(): first_thread=threading.Thread(target=first,name="T1") first_thread.start() print("main") if __name__ == '__main__': main()

      結(jié)果: frist active main frist finish

      因?yàn)閳?zhí)行到Frist active的時(shí)候Frist線程要睡3秒這個(gè)時(shí)候main還在執(zhí)行所以這樣每次都是這個(gè)結(jié)果了。

      特別強(qiáng)調(diào)target=first不是導(dǎo)入Frist函數(shù)從源文件我們就已經(jīng)看出是通過run()方法進(jìn)行的,這里解釋我引用一位大佬解釋

      當(dāng)然如果你覺得這樣不行的話你也可以重寫threading.Thresd里的run方法來個(gè)自定義線程

      class MyThread(threading.Thread): def __init__(self,n): super(MyThread,self).__init__() #重構(gòu)run函數(shù)必須寫 self.n = n def run(self): print('task',self.n) time.sleep(1) print('2s') time.sleep(1) print('1s') time.sleep(1) print('0s') time.sleep(1) if __name__ == '__main__': t1 = MyThread('t1') t2 = MyThread('t2') t1.start() t2.start()

      結(jié)果: task t1 task t2 2s 2s 1s 1s 0s 0s

      守護(hù)線程

      所謂’線程守護(hù)’,就是主線程不管該線程的執(zhí)行情況,只要是其他子線程結(jié)束且主線程執(zhí)行完畢,主線程都會(huì)關(guān)閉。也就是說:主線程不等待該守護(hù)線程的執(zhí)行完再去關(guān)閉。

      不好理解的話來看看例子

      import threading import time def first(): print("frist active") time.sleep(3) print("frist finish") def second(): print("second active") print("second finish") def main(): first_thread=threading.Thread(target=first,name="T1") second_thresd=threading.Thread(target=second,name="T2") first_thread.setDaemon(True)#一定要在start()前開始 first_thread.start() second_thresd.start() print("main") if __name__ == '__main__': main()

      結(jié)果 frist active second active second finishjiemeijieshu main

      當(dāng)主線程和其他子線程都結(jié)束不管守護(hù)線程first_thread 結(jié)沒結(jié)束程序都結(jié)束

      當(dāng)設(shè)second_thresd為守護(hù)線程的時(shí)候情況是這樣的

      import threading import time def first(): print("frist active") time.sleep(3) print("frist finish") def second(): print("second active") print("second finish") def main(): first_thread=threading.Thread(target=first,name="T1") second_thresd=threading.Thread(target=second,name="T2") second_thresd.setDaemon(True)#一定要在start()前開始 first_thread.start() second_thresd.start() print("main") if __name__ == '__main__': main()

      frist active second active second finish main frist finish #盡管輸出這個(gè)要等三秒

      主進(jìn)程等待子進(jìn)程結(jié)束

      為了讓守護(hù)線程執(zhí)行結(jié)束之后,主線程再結(jié)束,我們可以使用join方法,讓主線程等待子線程執(zhí)行

      import threading import time def first(): print("frist active") time.sleep(3) print("frist finish") def second(): print("second active") print("second finish") def main(): first_thread=threading.Thread(target=first,name="T1") second_thresd=threading.Thread(target=second,name="T2") first_thread.start() second_thresd.start() first_thread.join() print("main") if __name__ == '__main__': main()

      結(jié)果: frist active second active second finish frist finish main 不加join是這樣的結(jié)果 frist active second active second finish main frist finish

      共享全局變量的特性

      這里定義一個(gè)全局變量A

      import threading import time def first(): global A print("frist active") time.sleep(3) A=A+3 print("frist:%d"%A) print("frist finish") def second(): global A print("second active") A=A+6 print("second:%d"%A) print("second finish") def main(): global A first_thread=threading.Thread(target=first,name="T1") second_thresd=threading.Thread(target=second,name="T2") first_thread.start() second_thresd.start() #first_thread.join() print("main") A=A+3 print("mian:%d"%A) if __name__ == '__main__': A=0 main()

      來看一下結(jié)果

      frist active second active second:6 second finish main mian:9 frist:12 frist finish

      由上面的例子可以看出,輸出A的值的時(shí)候不同進(jìn)程之間的資源是共享的這就導(dǎo)致了變量A的值不固定造成了臟數(shù)據(jù)的情況,不理解的話我們就來個(gè)例子。

      在沒有互斥鎖的情況下,假設(shè)賬戶有一萬(wàn)元錢,存錢和取錢同時(shí)進(jìn)行可能賬戶余額會(huì)有一萬(wàn)一千元。這樣我當(dāng)然高興只是銀行不答應(yīng)。為了避免這種情況我們引入鎖的概念,下面我們簡(jiǎn)單的介紹幾種編程里面常用的。

      互斥鎖

      import threading import time def first(): global A,lock lock.acquire() print("frist active") time.sleep(3) A=A+3 print("frist:%d"%A) print("frist finish") lock.release() def second(): global A,lock lock.acquire() print("second active") A=A+6 print("second:%d"%A) print("second finish") lock.release def main(): global A,lock lock=threading.Lock() first_thread=threading.Thread(target=first,name="T1") second_thresd=threading.Thread(target=second,name="T2") first_thread.start() second_thresd.start() #first_thread.join() print("main") A=A+3 print("mian:%d"%A) if __name__ == '__main__': A=0 main()

      結(jié)果

      frist active main mian:3 frist:6 frist finish second active second:12 second finish

      是不是這樣看著就舒服多了,如果例子不夠明顯我們?cè)賮硪粋€(gè)

      import threading import time def first(): global A,lock lock.acquire() print("frist active") time.sleep(3) A=A+3 print("frist1:%d"%A) A = A + 3 print("frist2:%d" % A) print("frist finish") lock.release() def second(): global A,lock lock.acquire() print("second active") A=A+6 print("second1:%d"%A) A=A+6 print("second2:%d"%A) print("second finish") lock.release() def main(): global A,lock lock=threading.Lock() first_thread=threading.Thread(target=first,name="T1") second_thresd=threading.Thread(target=second,name="T2") first_thread.start() second_thresd.start() #first_thread.join() print("main") A=A+3 print("mian:%d"%A) if __name__ == '__main__': A=0 main()

      結(jié)果

      frist active main mian:3 frist1:6 frist2:9 frist finish second active second1:15 second2:21 second finish 去掉鎖以后結(jié)果 frist active second active second1:6 second2:12 second finish main mian:15 frist1:18 frist2:21 frist finish

      很明顯去掉鎖以后結(jié)果雜亂的很

      信號(hào)量

      我相信對(duì)操作系統(tǒng)有一定了解的肯定,在剛才提到鎖的時(shí)候就想到了信號(hào)量畢竟考研題經(jīng)常會(huì)出現(xiàn),同步,互斥和信號(hào)量機(jī)制。我們就來說一說信號(hào)量鎖,其實(shí)道理很簡(jiǎn)單假如你現(xiàn)在,在中國(guó)結(jié)婚了你只能娶一個(gè)老婆吧,盡管你可以去找別的女人但他們不能稱為老婆她們會(huì)被稱為小三,二奶啊等等,這里老婆這個(gè)信號(hào)量在中國(guó)就是==一==只能有一個(gè),別的再來就不可以了。

      import threading import time def run(n,semaphore): semaphore.acquire() #加鎖 time.sleep(3) print('run the thread:%s\n' % n) semaphore.release() #釋放 if __name__== '__main__': num=0 semaphore = threading.BoundedSemaphore(3) #最多允許3個(gè)線程同時(shí)運(yùn)行 for i in range(10): t = threading.Thread(target=run,args=('t-%s' % i,semaphore)) t.start() while threading.active_count() !=1: pass else: print('----------all threads done-----------')

      結(jié)果

      run the thread:t-2 run the thread:t-1 run the thread:t-0 run the thread:t-3 run the thread:t-5 run the thread:t-4 run the thread:t-6 run the thread:t-7 run the thread:t-8 run the thread:t-9 ----------all threads done-----------

      任務(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)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(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)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:word里面表格粘貼多了,在手機(jī)上能看到,電腦上看不到怎么回事兒(word表格文檔手機(jī)和電腦顯示不一樣)
      下一篇:excel 透視圖如何使用(excel函數(shù)公式大全)
      相關(guān)文章
      亚洲精品亚洲人成在线观看麻豆| 亚洲国模精品一区| 久久乐国产精品亚洲综合| 大桥未久亚洲无av码在线| 亚洲综合国产成人丁香五月激情 | 久久亚洲AV成人无码国产最大| 香蕉大伊亚洲人在线观看| 亚洲另类精品xxxx人妖| 91亚洲视频在线观看| 亚洲成a人片77777群色| 亚洲精品高清国产麻豆专区| 久久亚洲AV成人无码| 亚洲视频在线观看网站| 亚洲精品中文字幕无乱码| 亚洲精品成人网站在线播放| 亚洲视频免费播放| 亚洲国产成人精品青青草原| 亚洲国产精品久久丫| 亚洲av成人一区二区三区| 中文字幕亚洲码在线| 亚洲国产精品无码久久| 国产精品亚洲专区无码WEB| 国产成人综合亚洲| 亚洲欧洲一区二区三区| 国产亚洲精品无码拍拍拍色欲| 在线播放亚洲第一字幕| 亚洲成亚洲乱码一二三四区软件| 亚洲av一综合av一区| 精品亚洲A∨无码一区二区三区| 亚洲日韩乱码中文无码蜜桃| 亚洲伊人色一综合网| 亚洲色欲啪啪久久WWW综合网| 亚洲精品国产av成拍色拍| 国产成人不卡亚洲精品91 | 亚洲毛片基地日韩毛片基地| 亚洲人成人77777在线播放| 亚洲日韩精品无码AV海量| 国产精品亚洲综合一区在线观看 | 中文字幕在亚洲第一在线| 久久久久久久久亚洲| 亚洲欧洲另类春色校园小说|