Python中的多線程實(shí)例(簡單易懂)
前言:
多線程簡單理解就是:一個(gè)CPU,也就是單核,將時(shí)間切成一片一片的,CPU輪轉(zhuǎn)著去處理一件一件的事情,到了規(guī)定的時(shí)間片就處理下一件事情。
1.python中顯示當(dāng)前線程信息的屬性和方法
# coding:utf-8
# 導(dǎo)入threading包
import threading
if __name__ == "__main__":
print("當(dāng)前活躍線程的數(shù)量", threading.active_count())
print("將當(dāng)前所有線程的具體信息展示出來", threading.enumerate())
print("當(dāng)前的線程的信息展示", threading.current_thread())效果圖:

2.添加一個(gè)線程
# coding:utf-8
import threading
import time
def job1():
# 讓這個(gè)線程多執(zhí)行幾秒
time.sleep(5)
print("the number of T1 is %s" % threading.current_thread())
if __name__ == "__main__":
# 創(chuàng)建一個(gè)新的線程
new_thread = threading.Thread(target=job1, name="T1")
# 啟動(dòng)新線程
new_thread.start()
print("當(dāng)前線程數(shù)量為", threading.active_count())
print("所有線程的具體信息", threading.enumerate())
print("當(dāng)前線程具體信息", threading.current_thread())效果圖:

3.線程中的join函數(shù)
(1)預(yù)想的是,執(zhí)行完線程1,然后輸出All done…“理想很豐滿,現(xiàn)實(shí)卻不是這樣的”
# coding:utf-8
import threading
import time
def job1():
print("T1 start")
for i in range(5):
time.sleep(1)
print(i)
print("T1 finish")
def main():
# 新創(chuàng)建一個(gè)線程
new_thread = threading.Thread(target=job1, name="T1")
# 啟動(dòng)新線程
new_thread.start()
print("All done...")
if __name__ == "__main__":
main()效果圖:

(2)為了達(dá)到我們的預(yù)期,我們使用join函數(shù),將T1線程進(jìn)行阻塞。join函數(shù)進(jìn)行阻塞是什么意思?就是哪個(gè)線程使用了join函數(shù),當(dāng)這個(gè)線程正在執(zhí)行時(shí),在他之后的線程程序不能執(zhí)行,得等這個(gè)被阻塞的線程全部執(zhí)行完畢之后,方可執(zhí)行!
# coding:utf-8
import threading
import time
def job1():
print("T1 start")
for i in range(5):
time.sleep(1)
print(i)
print("T1 finish")
def main():
# 新創(chuàng)建一個(gè)線程
new_thread = threading.Thread(target=job1, name="T1")
# 啟動(dòng)新線程
new_thread.start()
# 阻塞這個(gè)T1線程
new_thread.join()
print("All done...")
if __name__ == "__main__":
main()效果圖:

4.使用Queue存儲線程的結(jié)果
線程的執(zhí)行結(jié)果,無法通過return進(jìn)行返回,使用Queue存儲。
# coding:utf-8
import threading
from queue import Queue
"""
Queue的使用
"""
def job(l, q):
for i in range(len(l)):
l[i] = l[i] ** 2
q.put(l)
def multithreading():
# 創(chuàng)建隊(duì)列
q = Queue()
# 線程列表
threads = []
# 二維列表
data = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [6, 6, 6]]
for i in range(4):
t = threading.Thread(target=job, args=(data[i], q))
t.start()
threads.append(t)
# 對所有線程進(jìn)行阻塞
for thread in threads:
thread.join()
results = []
# 將新隊(duì)列中的每個(gè)元素挨個(gè)放到結(jié)果列表中
for _ in range(4):
results.append(q.get())
print(results)
if __name__ == "__main__":
multithreading()效果圖:

5.線程鎖lock
當(dāng)同時(shí)啟動(dòng)多個(gè)線程時(shí),各個(gè)線程之間會(huì)互相搶占計(jì)算資源,會(huì)造成程序混亂。
舉個(gè)栗子:
當(dāng)我們在選課系統(tǒng)選課時(shí),當(dāng)前籃球課還有2個(gè)名額,我們?nèi)齻€(gè)人去選課。
選課順序?yàn)閟tu1 stu2 stu3,應(yīng)該依次打印他們?nèi)齻€(gè)的選課過程,但是現(xiàn)實(shí)情況卻是:
# coding:utf-8
import threading
import time
def stu1():
print("stu1開始選課")
global course
if course > 0:
course -= 1
time.sleep(2)
print("stu1選課成功,現(xiàn)在籃球課所剩名額為%d" % course)
else:
time.sleep(2)
print("stu1選課失敗,籃球課名額為0,請選擇其他課程")
def stu2():
print("stu2開始選課")
global course
if course > 0:
course -= 1
time.sleep(2)
print("stu2選課成功,現(xiàn)在籃球課所剩名額為%d" % course)
else:
time.sleep(2)
print("stu2選課失敗,籃球課名額為0,請選擇其他課程")
def stu3():
print("stu3開始選課")
global course
if course > 0:
course -= 1
time.sleep(2)
print("stu3選課成功")
print("籃球課所剩名額為%d" %course)
else:
time.sleep(2)
print("stu3選課失敗,籃球課名額為0,請選擇其他課程")
if __name__ == "__main__":
# 籃球課名額
course = 2
T1 = threading.Thread(target=stu1, name="T1")
T2 = threading.Thread(target=stu2, name="T2")
T3 = threading.Thread(target=stu3, name="T3")
T1.start()
T2.start()
T3.start()效果圖:

為了解決這種情況,我們使用lock線程同步鎖,在線程并發(fā)執(zhí)行時(shí),保證每個(gè)線程執(zhí)行的原子性。有效防止了共享統(tǒng)一數(shù)據(jù)時(shí),線程并發(fā)執(zhí)行的混亂。
改進(jìn)的代碼如下:
# coding:utf-8
import threading
import time
def stu1():
global lock
lock.acquire()
print("stu1開始選課")
global course
if course > 0:
course -= 1
time.sleep(2)
print("stu1選課成功,現(xiàn)在籃球課所剩名額為%d" % course)
else:
time.sleep(2)
print("stu1選課失敗,籃球課名額為0,請選擇其他課程")
lock.release()
def stu2():
global lock
lock.acquire()
print("stu2開始選課")
global course
if course > 0:
course -= 1
print("stu2選課成功,現(xiàn)在籃球課所剩名額為%d" % course)
else:
time.sleep(1)
print("stu2選課失敗,籃球課名額為0,請選擇其他課程")
lock.release()
def stu3():
global lock
lock.acquire()
print("stu3開始選課")
global course
if course > 0:
course -= 1
time.sleep(1)
print("stu3選課成功,現(xiàn)在籃球課所剩名額為%d" % course)
else:
time.sleep(1)
print("stu3選課失敗,籃球課名額為0,請選擇其他課程")
lock.release()
if __name__ == "__main__":
# 籃球課名額
course = 2
# 創(chuàng)建同步鎖
lock = threading.Lock()
T1 = threading.Thread(target=stu1, name="T1")
T2 = threading.Thread(target=stu2, name="T2")
T3 = threading.Thread(target=stu3, name="T3")
T1.start()
T2.start()
T3.start()效果圖:

到此這篇關(guān)于Python中的多線程實(shí)例(簡單易懂)的文章就介紹到這了,更多相關(guān)Python多線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)雙X軸雙Y軸繪圖的示例詳解
這篇文章主要介紹了如何利用fig.add_subplot和axes.twinx().twiny()方法實(shí)現(xiàn)雙X軸雙Y軸繪圖,文中的示例代碼講解詳細(xì),快跟隨小編一起動(dòng)手嘗試一下吧2022-04-04
Python通過樸素貝葉斯和LSTM分別實(shí)現(xiàn)新聞文本分類
樸素貝葉斯法(Naive Bayes model)是基于貝葉斯定理與特征條件獨(dú)立假設(shè)的分類方法。LSTM則是一種時(shí)間循環(huán)神經(jīng)網(wǎng)絡(luò),適合于處理和預(yù)測時(shí)間序列中間隔和延遲相對較長的重要事件。本文將通過這兩個(gè)方法分別實(shí)現(xiàn)新聞文本分類,需要的可以參考一下2021-12-12
對dataframe進(jìn)行列相加,行相加的實(shí)例
今天小編就為大家分享一篇對dataframe進(jìn)行列相加,行相加的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06

