欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Python多線程多函數(shù) python 多線程 函數(shù)

python多線程怎樣執(zhí)行函數(shù)

將你需要多線程并發(fā)執(zhí)行的函數(shù)放入list中

龍鳳ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)建站的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!

import threading

threads = []

t1 = threading.Thread(target=函數(shù)名,args=參數(shù))

threads.append(t1)

啟動多線程

if __name__ == '__main__':

??? for t in threads:

? ? ??? t.setDaemon(True)

? ? ??? t.start()

t.join()

更多詳細(xì)操作help(threading)

#coding=utf-8

import?threading

from?time?import?ctime,sleep

#?要啟動的函數(shù)

def?music(func):

for?i?in?range(2):

print?"I?was?listening?to?%s.?%s"?%(func,ctime())

sleep(1)

#?要啟動的函數(shù)

def?move(func):

for?i?in?range(2):

print?"I?was?at?the?%s!?%s"?%(func,ctime())

sleep(5)

threads?=?[]

t1?=?threading.Thread(target=music,args=(u'愛情買賣',))

threads.append(t1)

t2?=?threading.Thread(target=move,args=(u'阿凡達(dá)',))

threads.append(t2)

#?函數(shù)加入線程列表

if?__name__?==?'__main__':

for?t?in?threads:

t.setDaemon(True)

t.start()

t.join()?#子線程完成運行之前,這個子線程的父線程將一直被阻塞,不會退出

print?"all?over?%s"?%ctime()

python之多線程原理

并發(fā):邏輯上具備同時處理多個任務(wù)的能力。

并行:物理上在同一時刻執(zhí)行多個并發(fā)任務(wù)。

舉例:開個QQ,開了一個進(jìn)程,開了微信,開了一個進(jìn)程。在QQ這個進(jìn)程里面,傳輸文字開一個線程、傳輸語音開了一個線程、彈出對話框又開了一個線程。

總結(jié):開一個軟件,相當(dāng)于開了一個進(jìn)程。在這個軟件運行的過程里,多個工作同時運轉(zhuǎn),完成了QQ的運行,那么這個多個工作分別有多個線程。

線程和進(jìn)程之間的區(qū)別:

進(jìn)程在python中的使用,對模塊threading進(jìn)行操作,調(diào)用的這個三方庫。可以通過 help(threading) 了解其中的方法、變量使用情況。也可以使用 dir(threading) 查看目錄結(jié)構(gòu)。

current_thread_num = threading.active_count() # 返回正在運行的線程數(shù)量

run_thread_len = len(threading.enumerate()) # 返回正在運行的線程數(shù)量

run_thread_list = threading.enumerate() # 返回當(dāng)前運行線程的列表

t1=threading.Thread(target=dance) #創(chuàng)建兩個子線程,參數(shù)傳遞為函數(shù)名

t1.setDaemon(True) # 設(shè)置守護(hù)進(jìn)程,守護(hù)進(jìn)程:主線程結(jié)束時自動退出子線程。

t1.start() # 啟動子線程

t1.join() # 等待進(jìn)程結(jié)束 exit()`# 主線程退出,t1子線程設(shè)置了守護(hù)進(jìn)程,會自動退出。其他子線程會繼續(xù)執(zhí)行。

多線程和隊列

1、python提供兩種方式使用多線程:一個是基于函數(shù):_thread模塊或者threading模塊。一個是基于類:theading.Thread

使用多線程函數(shù)包裝線程對象:_thread

_thead.start_new_thead(func,*args,**kwargs)

args,**kwargs是被包裝函數(shù)的入?yún)ⅲ仨殏魅朐婊蜃值?/p>

使用多線程函數(shù)包裝線程對象:threading

threading._start_new_thread(func,*args,**kwargs):開啟線程,帶元祖或字典

threading.currentThread():返回當(dāng)前線程變量

threading.enumerate():正在運行的線程列表,不含未啟動和已結(jié)束線程

threading.activeCount():返回正在運行的線程數(shù)量

threading.settrace(func):為所有threading模塊啟動的線程設(shè)置追蹤函數(shù),在調(diào)用run方法之前,func會被傳給追蹤函數(shù)

threading.setprofile(func):為所有threading模塊啟動的線程設(shè)置性能測試函數(shù),也是在run方法調(diào)用前就傳遞給性能測試函數(shù)

使用多線程類包裝線程對象:threading.Thread

Thread類提供以下方法:

run():表示線程活動的方法,線程需要控制些什么活動都在這里面定義。當(dāng)線程對象一但被創(chuàng)建,其活動一定會因調(diào)用線程的 start() 方法開始。這會在獨立的控制線程調(diào)用 run() 方法。

start():開啟線程活動

join():等待線程中止,阻塞當(dāng)前線程直到被調(diào)用join方法的線程中止。線程A調(diào)用線程B的join方法,那線程A將會被阻塞至線程B中止。

isAlive():返回線程是否還活動

getName():獲取線程名字

setName():設(shè)置線程名字

Lock對象:實例化線程鎖,包含acquire方法獲取鎖 和 release 方法釋放鎖,在最開始創(chuàng)建鎖的時候,鎖為未鎖定狀態(tài),調(diào)用acquire方法后鎖置為鎖定狀態(tài),此時其他線程再調(diào)用acquire方法就將會被阻塞至其他線程調(diào)用release方法釋放鎖,如果釋放一個并未被鎖定的鎖將會拋出異常。支持上下文管理協(xié)議,直接with lock 無需調(diào)用鎖定,釋放方法

Rlock對象:重入鎖,相比lock增加了線程和遞歸的概念。比如:線程目標(biāo)函數(shù)F,在獲得鎖之后執(zhí)行函數(shù)G,但函數(shù)G也需要先獲得鎖,此時同一線程,F(xiàn)獲得鎖,G等待,F(xiàn)等待G執(zhí)行,就造成了死鎖,此時使用rlock可避免。一旦線程獲得了重入鎖,同一個線程再次獲取它將不阻塞;但線程必須在每次獲取它時釋放一次。

daemon屬性:設(shè)置該線程是否是守護(hù)線程,默認(rèn)為none,需要在調(diào)用start方法之前設(shè)置好

事件對象:一個線程發(fā)出事件信號 ,其他線程收到信號后作出對應(yīng)活動。實例化事件對象后,初始事件標(biāo)志為flase。調(diào)用其wait方法將阻塞當(dāng)前所屬線程,至事件標(biāo)志為true時。調(diào)用set方法可將事件標(biāo)志置為true,被阻塞的線程將被執(zhí)行。調(diào)用clear方法可將事件標(biāo)志置為flase

注意點:

1、繼承threading.Thread類,初始化時要記得繼承父類的__init__方法

2、run()方法只能有一個入?yún)ⅲ时M量把啟動線程時的參數(shù)入?yún)⒌匠跏蓟臅r候

3、鎖要設(shè)定全局的,一個子線程獲得一個鎖沒有意義

以下實例:有一個列表,線程A從尾到頭遍歷元素,線程B從頭到尾將元素值重置為1,設(shè)置線程鎖之前線程A遍歷到頭部的數(shù)據(jù)已經(jīng)被修改,設(shè)置線程鎖之后不會再有數(shù)據(jù)不一致的情況

import threading,time

class tt(threading.Thread):

def __init__(self,name,func,ll):

? ? threading.Thread.__init__(self) #繼承父級的初始化方法

? ? self.name=name

? ? self.func=func? #run方法只能帶一個入?yún)ⅲ拾逊椒ㄈ雲(yún)⒌匠跏蓟臅r候

? ? self.ll=ll

def run(self):

? ? print(self.name)

? ? threadlock.acquire() #獲得鎖

? ? self.func(self.ll)

? ? threadlock.release() #釋放鎖

def readd(x):

a=len(x)

while a0:

? ? print(x[a-1])

? ? a-=1

def sett(x):

for i in range(len(x)):

? ? x[i]=1

print(x)

if __name__=="__main__":

l = [0,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

threadlock=threading.Lock() #實例化全局鎖

th1=tt("read",readd,l)

th2=tt("set",sett,l)

th1.start()

th2.start()

th_list=[]?

th_list.append(th1)

th_list.append(th2)

for li in th_list:

? ? li.join()? ? ? ? #主線程被阻塞,直到兩個子線程處理結(jié)束

print("主線程結(jié)束")

2、隊列

queue模塊包含queue.Queue(maxsize=0)先入先出隊列,queue.LifoQueue()先入后出隊列,和queue.PriorityQueue()優(yōu)先級可設(shè)置的隊列

Queue 模塊中的常用方法:

Queue.qsize() 返回隊列的大小,獲取的數(shù)據(jù)不可靠,因為一直有線程在操作隊列,數(shù)據(jù)一直變化

Queue.empty() 如果隊列為空,返回True,反之False

Queue.full() 如果隊列滿了,返回True,反之False

Queue.full 與 maxsize 大小對應(yīng)

Queue.put(block=true,timeout=none) 將item數(shù)據(jù)寫入隊列,block=True,設(shè)置線程是否阻塞,設(shè)置阻塞當(dāng)隊列數(shù)據(jù)滿了之后就會阻塞,一直到隊列數(shù)據(jù)不滿時繼續(xù)添加,如果設(shè)置不阻塞,當(dāng)隊列滿了就會一直到timeout到后報錯

Queue.get([block[, timeout]]) 取出隊列數(shù)據(jù),block=True,設(shè)置線程是否阻塞。設(shè)置阻塞,將會等待直到隊列不為空有數(shù)據(jù)可取出,設(shè)置不阻塞直到超過timeout等待時間后報錯

Queue.task_done() 在完成一項工作之后,Queue.task_done()函數(shù)向任務(wù)已經(jīng)完成的隊列發(fā)送一個信號

Queue.join() 實際上意味著等到隊列為空,再執(zhí)行別的操作。會在隊列有未完成時阻塞,等待隊列無未完成的任務(wù),取出數(shù)據(jù)get()之后還需要配置task_done使用才能讓等待隊列數(shù)-1

import queue,time

import threading

q=queue.Queue(maxsize=5)

def sett():

a=0

while a20:

? ? q.put(a,True)

? ? print("%d被put"%a)

? ? a+=1

def gett():

time.sleep(1)

while not q.empty(): #只要隊列沒空,一直取數(shù)據(jù)

? ? print("%d被取出"%q.get(True))

? ? q.task_done() #取出一次數(shù)據(jù),將未完成任務(wù)-1,不然使用join方法線程會一直阻塞

if __name__=="__main__":

th1=threading._start_new_thread(sett,()) #不帶參數(shù)也要傳入空元祖不然會報錯

th2=threading._start_new_thread(gett,())

time.sleep(1) #延時主線程1S,等待put線程已經(jīng)put部分?jǐn)?shù)據(jù)到隊列

q.join()#阻塞主線程,直到未完成任務(wù)為0

Python多線程總結(jié)

在實際處理數(shù)據(jù)時,因系統(tǒng)內(nèi)存有限,我們不可能一次把所有數(shù)據(jù)都導(dǎo)出進(jìn)行操作,所以需要批量導(dǎo)出依次操作。為了加快運行,我們會采用多線程的方法進(jìn)行數(shù)據(jù)處理, 以下為我總結(jié)的多線程批量處理數(shù)據(jù)的模板:

主要分為三大部分:

共分4部分對多線程的內(nèi)容進(jìn)行總結(jié)。

先為大家介紹線程的相關(guān)概念:

在飛車程序中,如果沒有多線程,我們就不能一邊聽歌一邊玩飛車,聽歌與玩 游戲 不能并行;在使用多線程后,我們就可以在玩 游戲 的同時聽背景音樂。在這個例子中啟動飛車程序就是一個進(jìn)程,玩 游戲 和聽音樂是兩個線程。

Python 提供了 threading 模塊來實現(xiàn)多線程:

因為新建線程系統(tǒng)需要分配資源、終止線程系統(tǒng)需要回收資源,所以如果可以重用線程,則可以減去新建/終止的開銷以提升性能。同時,使用線程池的語法比自己新建線程執(zhí)行線程更加簡潔。

Python 為我們提供了 ThreadPoolExecutor 來實現(xiàn)線程池,此線程池默認(rèn)子線程守護(hù)。它的適應(yīng)場景為突發(fā)性大量請求或需要大量線程完成任務(wù),但實際任務(wù)處理時間較短。

其中 max_workers 為線程池中的線程個數(shù),常用的遍歷方法有 map 和 submit+as_completed 。根據(jù)業(yè)務(wù)場景的不同,若我們需要輸出結(jié)果按遍歷順序返回,我們就用 map 方法,若想誰先完成就返回誰,我們就用 submit+as_complete 方法。

我們把一個時間段內(nèi)只允許一個線程使用的資源稱為臨界資源,對臨界資源的訪問,必須互斥的進(jìn)行。互斥,也稱間接制約關(guān)系。線程互斥指當(dāng)一個線程訪問某臨界資源時,另一個想要訪問該臨界資源的線程必須等待。當(dāng)前訪問臨界資源的線程訪問結(jié)束,釋放該資源之后,另一個線程才能去訪問臨界資源。鎖的功能就是實現(xiàn)線程互斥。

我把線程互斥比作廁所包間上大號的過程,因為包間里只有一個坑,所以只允許一個人進(jìn)行大號。當(dāng)?shù)谝粋€人要上廁所時,會將門上上鎖,這時如果第二個人也想大號,那就必須等第一個人上完,將鎖解開后才能進(jìn)行,在這期間第二個人就只能在門外等著。這個過程與代碼中使用鎖的原理如出一轍,這里的坑就是臨界資源。 Python 的 threading 模塊引入了鎖。 threading 模塊提供了 Lock 類,它有如下方法加鎖和釋放鎖:

我們會發(fā)現(xiàn)這個程序只會打印“第一道鎖”,而且程序既沒有終止,也沒有繼續(xù)運行。這是因為 Lock 鎖在同一線程內(nèi)第一次加鎖之后還沒有釋放時,就進(jìn)行了第二次 acquire 請求,導(dǎo)致無法執(zhí)行 release ,所以鎖永遠(yuǎn)無法釋放,這就是死鎖。如果我們使用 RLock 就能正常運行,不會發(fā)生死鎖的狀態(tài)。

在主線程中定義 Lock 鎖,然后上鎖,再創(chuàng)建一個子 線程t 運行 main 函數(shù)釋放鎖,結(jié)果正常輸出,說明主線程上的鎖,可由子線程解鎖。

如果把上面的鎖改為 RLock 則報錯。在實際中設(shè)計程序時,我們會將每個功能分別封裝成一個函數(shù),每個函數(shù)中都可能會有臨界區(qū)域,所以就需要用到 RLock 。

一句話總結(jié)就是 Lock 不能套娃, RLock 可以套娃; Lock 可以由其他線程中的鎖進(jìn)行操作, RLock 只能由本線程進(jìn)行操作。

名稱欄目:Python多線程多函數(shù) python 多線程 函數(shù)
文章網(wǎng)址:http://chinadenli.net/article48/hhjoep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航網(wǎng)站營銷網(wǎng)站設(shè)計網(wǎng)站維護(hù)網(wǎng)站收錄企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運營