導航:首頁 > 編程語言 > python怎麼多線程並發

python怎麼多線程並發

發布時間:2023-04-01 23:59:02

1. python多線程幾種方法實現

Python進階(二十六)-多線程實現同步的四種方式
臨界資源即那些一次只能被一個線程訪問的資源,典型例子就是列印機,它一次只能被一個程序用來執行列印功能,因為不能多個線程同時操作,而訪問這部分資源的代碼通常稱之為臨界區。
鎖機制
threading的Lock類,用該類的acquire函數進行加鎖,用realease函數進行解鎖
import threadingimport timeclass Num:
def __init__(self):
self.num = 0
self.lock = threading.Lock() def add(self):
self.lock.acquire()#加鎖,鎖住相應的資源
self.num += 1
num = self.num
self.lock.release()#解鎖,離開該資源
return num

n = Num()class jdThread(threading.Thread):
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item def run(self):
time.sleep(2)
value = n.add()#將num加1,並輸出原來的數據和+1之後的數據
print(self.item,value)for item in range(5):
t = jdThread(item)
t.start()
t.join()#使線程一個一個執行

當一個線程調用鎖的acquire()方法獲得鎖時,鎖就進入「locked」狀態。每次只有一個線程可以獲得鎖。如果此時另一個線程試圖獲得這個鎖,該線程就會變為「blocked」狀態,稱為「同步阻塞」(參見多線程的基本概念)。
直到擁有鎖的線程調用鎖的release()方法釋放鎖之後,鎖進入「unlocked」狀態。線程調度程序從處於同步阻塞狀態的線程中選擇一個來獲得鎖,並使得該線程進入運行(running)狀態。
信號量
信號量也提供acquire方法和release方法,每當調用acquire方法的時候,如果內部計數器大於0,則將其減1,如果內部計數器等於0,則會阻塞該線程,知道有線程調用了release方法將內部計數器更新到大於1位置。
import threadingimport timeclass Num:
def __init__(self):
self.num = 0
self.sem = threading.Semaphore(value = 3) #允許最多三個線程同時訪問資源

def add(self):
self.sem.acquire()#內部計數器減1
self.num += 1
num = self.num
self.sem.release()#內部計數器加1
return num

n = Num()class jdThread(threading.Thread):
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item def run(self):
time.sleep(2)
value = n.add()
print(self.item,value)for item in range(100):

2. python實現多線程並發執行

由於停服維護的需求(服務越來越多的原因),此前編寫的shell腳本執行速度緩慢(for循環,這就會很慢),為提高執行速度,參考很多資料,完成此腳本,實現並發執行機制.(當然這是測試腳本,有需要的同學,拿去改ba改ba,應該就可以用了)

此處腳本參考了 https://www.jb51.net/article/86053.htm

3. python多線程並行計算通過向線程池ThreadPoolExecutor提交任務的實現方法

Python的線程池可以有效地控制系統中並發線程的數量。
當程序中需要創建許多生存期較短的線程執行運算任務時,首先考慮使用線程池。線程池任務啟動時會創建出最大線程數參數 max_workers 指定數量的空閑線程,程序只要將執行函數提交給線程池,線程池就會啟動一個空閑的線程來執行它。當該函數執行結束後,該線程並不會死亡,而是再次返回到線程池中變成空閑狀態,等待執行下一個函數。配合使用 with 關鍵字實現任務隊列完成後自動關閉線程池釋放資源。

4. python多線程並發數量控制

python多線程如果不進行並發數量控制,在啟動線程數量多到一定程度後,會造成線程無法啟動的錯誤。
控制多線程並發數量的方法有好幾鍾,下面介紹用queue控制多線程並發數量的方法。python3

5. Python的多進程模塊multiprocessing

眾所周知,Python中不存在真正的多線程,Python中的多線程是一個並發過程。如果想要並行的執行程序,充分的利用cpu資源(cpu核心),還是需要使用多進程解決的。其中multiprocessing模塊應該是Python中最常用的多進程模塊了。

基本上multiprocessing這個模塊和threading這個模塊用法是相同的,也是可以通過函數和類創建進程。

上述案例基本上就是筆者搬用了上篇文章多線程的案例,可見其使用的相似之處。導入multiprocessing後實例化Process就可以創建一個進程,參數的話也是和多線程一樣,target放置進程執行函數,args存放該函數的參數。

使用類來創建進程也是需要先繼承multiprocessing.Process並且實現其init方法。

Pool可以提供指定數量的進程,供用戶調用,當有新的請求提交到pool中時,如果池還沒有滿,那麼就會創建一個新的進程用來執行該請求。

但如果池中的進程數已經達到規定最大值,那麼該請求就會等待,直到池中有進程結束,才會創建新的進程。

需要注意的是,在調用join方法阻塞進程前,需要先調用close方法,,否則程序會出錯。

在上述案例中,提到了非阻塞,當把創建進程的方法換為pool.apply(func, (msg,))時,就會阻塞進程,出現下面的狀況。

在multiprocessing模塊中還存在Queue對象,這是一個進程的安全隊列,近似queue.Queue。隊列一般也是需要配合多線程或者多進程使用。

下列案例是一個使用進程隊列實現的生產者消費者模式。

multiprocessing支持兩種進程間的通信,其中一種便是上述案例的隊列,另一種則稱作管道。在官方文檔的描述中,multiprocessing中的隊列是基於管道實現的,並且擁有更高的讀寫效率。

管道可以理解為進程間的通道,使用Pipe([plex])創建,並返回一個元組(conn1,conn2)。如果plex被置為True(默認值),那麼該管道是雙向的,如果plex被置為False,那麼該管道是單向的,即conn1隻能用於接收消息,而conn2僅能用於發送消息。

其中conn1、conn2表示管道兩端的連接對象,每個連接對象都有send()和recv()方法。send和recv方法分別是發送和接受消息的方法。例如,可以調用conn1.send發送消息,conn1.recv接收消息。如果沒有消息可接收,recv方法會一直阻塞。如果管道已經被關閉,那麼recv方法會拋出EOFError。

關於multiprocessing模塊其實還有很多實用的類和方法,由於篇幅有限(懶),筆者就先寫到這里。該模塊其實用起來很像threading模塊,像鎖對象和守護線程(進程)等multiprocessing模塊也是有的,使用方法也近乎相同。

如果想要更加詳細的了解multiprocessing模塊,請參考官方文檔。

6. Python中的多進程與多線程/分布式該如何使用

Python提供了非常好用的多進程包multiprocessing,你只需要定義一個函數,Python會替你完成其他所有事情。
藉助這個包,可以輕松完成從單進程到並發執行的轉換。
1、新建單一進程
如果我們新建少量進程,可以如下:
import multiprocessing
import time
def func(msg):
for i in xrange(3):
print msg
time.sleep(1)
if __name__ == "__main__":
p = multiprocessing.Process(target=func, args=("hello", ))
p.start()
p.join()
print "Sub-process done."12345678910111213
2、使用進程池
是的,你沒有看錯,不是線程池。它可以讓你跑滿多核CPU,而且使用方法非常簡單。
注意要用apply_async,如果落下async,就變成阻塞版本了。
processes=4是最多並發進程數量。
import multiprocessing
import time
def func(msg):
for i in xrange(3):
print msg
time.sleep(1)
if __name__ == "__main__":
pool = multiprocessing.Pool(processes=4)
for i in xrange(10):
msg = "hello %d" %(i)
pool.apply_async(func, (msg, ))
pool.close()
pool.join()
print "Sub-process(es) done."12345678910111213141516
3、使用Pool,並需要關注結果
更多的時候,我們不僅需要多進程執行,還需要關注每個進程的執行結果,如下:
import multiprocessing
import time
def func(msg):
for i in xrange(3):
print msg
time.sleep(1)
return "done " + msg
if __name__ == "__main__":
pool = multiprocessing.Pool(processes=4)
result = []
for i in xrange(10):
msg = "hello %d" %(i)
result.append(pool.apply_async(func, (msg, )))
pool.close()
pool.join()
for res in result:
print res.get()
print "Sub-process(es) done."
2014.12.25更新
根據網友評論中的反饋,在Windows下運行有可能崩潰(開啟了一大堆新窗口、進程),可以通過如下調用來解決:
multiprocessing.freeze_support()1
附錄(自己的腳本):
#!/usr/bin/python
import threading
import subprocess
import datetime
import multiprocessing
def dd_test(round, th):
test_file_arg = 'of=/zbkc/test_mds_crash/1m_%s_%s_{}' %(round, th)
command = "seq 100 | xargs -i dd if=/dev/zero %s bs=1M count=1" %test_file_arg
print command
subprocess.call(command,shell=True,stdout=open('/dev/null','w'),stderr=subprocess.STDOUT)
def mds_stat(round):
p = subprocess.Popen("zbkc mds stat", shell = True, stdout = subprocess.PIPE)
out = p.stdout.readlines()
if out[0].find('active') != -1:
command = "echo '0205pm %s round mds status OK, %s' >> /round_record" %(round, datetime.datetime.now())
command_2 = "time (ls /zbkc/test_mds_crash/) 2>>/round_record"
command_3 = "ls /zbkc/test_mds_crash | wc -l >> /round_record"
subprocess.call(command,shell=True)
subprocess.call(command_2,shell=True)
subprocess.call(command_3,shell=True)
return 1
else:
command = "echo '0205 %s round mds status abnormal, %s, %s' >> /round_record" %(round, out[0], datetime.datetime.now())
subprocess.call(command,shell=True)
return 0
#threads = []
for round in range(1, 1600):
pool = multiprocessing.Pool(processes = 10) #使用進程池
for th in range(10):
# th_name = "thread-" + str(th)
# threads.append(th_name) #添加線程到線程列表
# threading.Thread(target = dd_test, args = (round, th), name = th_name).start() #創建多線程任務
pool.apply_async(dd_test, (round, th))
pool.close()
pool.join()
#等待線程完成
# for t in threads:
# t.join()
if mds_stat(round) == 0:
subprocess.call("zbkc -s",shell=True)
break

7. Python中級精華-並發之啟動和停止線程

為了讓代碼能夠並發執行,向創建線程並在核實的時候銷毀它。

由於目的比較單純,只是講解基礎的線程創建方法,所以可以直接使用threading庫中的Thread類來實例化一個線程對象。

例子,用戶輸入兩個數字,並且求其兩個數字的四則運算的結果:

除了以上的一些功能以外,在python線程

中沒有其他的諸如給線程發信號、設置線程調度屬性、執行任何其他高級操作的功能了,如果需要這些功能,就需要手工編寫了。

另外,需要注意的是,由於GIL(全局解釋器鎖)的存在,限制了在python解釋器當中只允許運行一個線程。基於這個原因,不停該使用python線程來處理計算密集型的任務,因為在這種任務重我們希望在多個CPU核心上實現並行處理。Python線程更適合於IO處理以及設計阻塞操作的並發執行任務(即等待IO響應或等待資料庫取出結果等)。

如何判斷線程是否已經啟動?

目的:我們載入了一個線程,但是想要知道這個線程什麼時候才會開始運行?

方法:

線程的核心特徵我認為就是不確定性,因為其什麼時候開始運行,什麼時候被打斷,什麼時候恢復執行,這不是程序員能夠控制的,而是有系統調度

來完成的。如果遇到像某個線程的運行依託於其他某個線程運行到某個狀態時該線程才能開始運行,那麼這就是線程同步

問題,同樣這個問題非常棘手。要解決這類問題我們要藉助threading中的Event對象。

Event其實和條件標記類似,勻速線程

等待某個時間發生。初始狀態時事件被設置成0。如果事件沒有被設置而線程正在等待該事件,那麼線程就會被阻塞,直到事件被設置位置,當有線程設置了這個事件之後,那麼就會喚醒正在等待事件的線程,如果線程等待的事件已經設置了,那麼線程會繼續執行。

一個例子:

如上能夠確定的是,主線程會在線程t運行結束時再運行。

8. Python如何實現並行的多線程

Python中使用線程有兩種方式:函數或者用類來包裝線程對象。函數式:調用thread模塊中的start_new_thread()函數來產生新線程。線程模塊:Python通過兩個標准庫thread和threading提供對線程的支持。

9. python stackless 怎麼多線程並發

1 介紹

1.1 為什麼要使用Stackless

摘自stackless網站。

Note

Stackless Python 是Python編程語言的一個增強版本,它使程序員從基於線程的編程方式中獲得好處,並避免傳統線程所帶來的性能與復雜度問題。Stackless為 Python帶來的微線程擴展,是一種低開銷、輕量級的便利工具,如果使用得當,可以獲益如下:

閱讀全文

與python怎麼多線程並發相關的資料

熱點內容
看電影不要會員的網站 瀏覽:894
已知演算法文法G如下S 瀏覽:710
程序員周先生彩票 瀏覽:836
免費韓國中文倫理電影 瀏覽:975
大上海片尾曲 瀏覽:35
在哪裡可以看vr電視劇免費 瀏覽:15
steam的啟動項在文件夾的哪裡 瀏覽:374
午夜宅男看片網站 瀏覽:491
煤氣解壓伐不是加減調節是數字 瀏覽:123
對越自衛反擊戰電影大全集 影片 瀏覽:766
百度網盤小說資源 瀏覽:915
電影院第三排 瀏覽:516
sp兄弟訓誡文推薦 瀏覽:52
反垃圾雲網關如何防止郵件伺服器 瀏覽:716
韓國倫理電影翠花 瀏覽:83
電影提前看完整版 瀏覽:699
有個寶媽購物app叫什麼物 瀏覽:507
韓國倫理電影盲人男孩和戴墨鏡的醜女 瀏覽:729
美女被鬼強干 瀏覽:893
java得到伺服器的ip地址 瀏覽:502