Python-線程、線程池

1. Python多線程

python3中常用的線程模塊為:_thread(Python2中的thread)袁梗、threading(推薦)
線程池:ThreadPoolExecutor

2. 使用線程

第一種方式:

_thread.start_new_thread(function,args[,kwargs])
function:線程函數(shù)
args:傳遞給線程函數(shù)的參數(shù)撬统,必須是tuple(元組)類型
kwargs:可選參數(shù)

第二種方式

import threading
import time
import traceback

class MyThread(threading.Thread):
    def __init__(self, thread_id, thread_name, counter):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.thread_name = thread_name
        self.counter = counter

    def run(self):
        print_time(self.thread_name, 1, self.counter)

def print_time(thread_name, delay, counter):
    while counter:
        time.sleep(delay)
        print('%s : %s ' % (thread_name, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())))
        counter -= 1

thread1 = MyThread(1, 'time_thread_1', 5)
thread1.start()

3. thread內(nèi)部方法

1.threading.currentThread():返回當前的線程變量两曼;
2.threading.enumerate():返回當前正在運行的線程list,正在運行是指線程啟動后、結(jié)束前斧散;
3.threading.activeCount():返回當前正在運行的線程數(shù)供常,與len(threading.enumerate())相同
4.run():用以表示線程互動的方法
5.start():啟動線程
6.join([time]):等待線程終止,阻塞線程,直至join被調(diào)用或者線程中止鸡捐、正常退出或者異常栈暇,或者超時[time]
7.isAlive():返回線程是否存活
8.getName():線程名
9.setName():設(shè)置線程名

4. 線程同步

如果多個線程同時修改某個數(shù)據(jù)可能會導(dǎo)致數(shù)據(jù)的正確性,所以需要對線程進行同步處理箍镜,使用 Thread 對象的 Lock 和 Rlock 可以實現(xiàn)簡單的線程同步源祈,這兩個對象都有 acquire 方法和 release 方法,對于那些需要每次只允許一個線程操作的數(shù)據(jù)色迂,可以將其操作放到 acquire 和 release 方法之間香缺。

如下實例,多個線程同時進行對某個數(shù)據(jù)進行自增脚草,未加鎖時結(jié)果會怎么樣赫悄?

import threading

class MyThread(threading.Thread):
    def __init__(self, thread_id, thread_name):
        threading.Thread.__init__(self)
        self.thread_id = thread_id
        self.thread_name = thread_name

    def run(self):
        #獲取鎖
        # threadLock.acquire()
        global number
        for i in range(1, 1000000):
            number += 1
        #釋放鎖
        # threadLock.release()

threadLock = threading.Lock()

number = 1

thread = MyThread(1, 'thread')
thread.start()

thread2 = MyThread(2, 'thread2')
thread2.start()
計算結(jié)果=1999999 ? 1313434

Process finished with exit code 0

如果把加鎖的注釋去掉會怎么樣呢?

    def run(self):
        #獲取鎖
        threadLock.acquire()
        global number
        for i in range(1, 1000000):
            number += 1
        #釋放鎖
        threadLock.release()
計算結(jié)果=1999999 ? 1999999

Process finished with exit code 0

5. 線程池

1. 線程池介紹

線程池在系統(tǒng)啟動時即創(chuàng)建大量空閑的線程馏慨,程序只要將一個函數(shù)提交給線程池埂淮,線程池就會啟動一個空閑的線程來執(zhí)行它。當該函數(shù)執(zhí)行結(jié)束后写隶,該線程并不會死亡倔撞,而是再次返回到線程池中變成空閑狀態(tài),等待執(zhí)行下一個函數(shù)慕趴。
使用線程池可以有效地控制系統(tǒng)中并發(fā)線程的數(shù)量痪蝇。當系統(tǒng)中包含有大量的并發(fā)線程時,會導(dǎo)致系統(tǒng)性能急劇下降冕房,甚至導(dǎo)致 Python 解釋器崩潰躏啰,而線程池的最大線程數(shù)參數(shù)可以控制系統(tǒng)中并發(fā)線程的數(shù)量不超過此數(shù)。

2.線程池的使用

線程池的基類是 concurrent.futures 模塊中的 Executor耙册,Executor 提供了兩個子類给僵,即 ThreadPoolExecutor 和 ProcessPoolExecutor,其中 ThreadPoolExecutor 用于創(chuàng)建線程池,而 ProcessPoolExecutor 用于創(chuàng)建進程池帝际。

Exectuor 提供了如下常用方法:
submit(fn, *args, **kwargs):將 fn 函數(shù)提交給線程池蔓同。*args 代表傳給 fn 函數(shù)的參數(shù),*kwargs 代表以關(guān)鍵字參數(shù)的形式為 fn 函數(shù)傳入?yún)?shù)蹲诀。
map(func, *iterables, timeout=None, chunksize=1):該函數(shù)類似于全局函數(shù) map(func, *iterables)斑粱,只是該函數(shù)將會啟動多個線程,以異步方式立即對 iterables 執(zhí)行 map 處理脯爪。
shutdown(wait=True):關(guān)閉線程池则北。

submit 方法會返回一個 Future 對象
Future 提供了如下方法:

cancel():取消該 Future 代表的線程任務(wù)。如果該任務(wù)正在執(zhí)行披粟,不可取消咒锻,則該方法返回 False;否則守屉,程序會取消該任務(wù)惑艇,并返回 True。
cancelled():返回 Future 代表的線程任務(wù)是否被成功取消拇泛。
running():如果該 Future 代表的線程任務(wù)正在執(zhí)行滨巴、不可被取消,該方法返回 True俺叭。
done():如果該 Funture 代表的線程任務(wù)被成功取消或執(zhí)行完成,則該方法返回 True熄守。
result(timeout=None):獲取該 Future 代表的線程任務(wù)最后返回的結(jié)果蜈垮。如果 Future 代表的線程任務(wù)還未完成,該方法將會阻塞當前線程裕照,其中 timeout 參數(shù)指定最多阻塞多少秒攒发。
exception(timeout=None):獲取該 Future 代表的線程任務(wù)所引發(fā)的異常。如果該任務(wù)成功完成晋南,沒有異常惠猿,則該方法返回 None。
add_done_callback(fn):為該 Future 代表的線程任務(wù)注冊一個“回調(diào)函數(shù)”负间,當該任務(wù)成功完成時偶妖,程序會自動觸發(fā)該 fn 函數(shù)。

在用完一個線程池后政溃,應(yīng)該調(diào)用該線程池的 shutdown() 方法趾访,該方法將啟動線程池的關(guān)閉序列。調(diào)用 shutdown() 方法后的線程池不再接收新任務(wù)董虱,但會將以前所有的已提交任務(wù)執(zhí)行完成腹缩。當線程池中的所有任務(wù)都執(zhí)行完成后,該線程池中的所有線程都會死亡空扎。

from concurrent.futures import ThreadPoolExecutor
import threading, time


class WorkThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self) -> None:
        print('start run task')
        time.sleep(2)
        print('task finish\n')
        return '線程類執(zhí)行完成'

def test(thread_name):
    print(thread_name, threading.current_thread().name)
    time.sleep(5)
    print('任務(wù)完成\n')
    return '線程方法執(zhí)行完成'

f __name__ == '__main__':
    thread_pool = ThreadPoolExecutor(5)
    futures = []
    for i in range(7):
        thraed = WorkThread()
        # sumit(方法名藏鹊,參數(shù))
        future1 = thread_pool.submit(thraed.run)
        future2 = thread_pool.submit(test, i)
        futures.append(future1)
        futures.append(future2)

    def get_call_back(future):
        # 監(jiān)聽任務(wù)執(zhí)行結(jié)果,當前線程一直阻塞知道有結(jié)果转锈,但是不阻塞主線程
        print(future.result())

    for future in futures:
        #添加監(jiān)聽
        future.add_done_callback(get_call_back)

     print('main thread')

map執(zhí)行線程
啟動三個線程

thread_pool.map(test, (2,3,4))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盘寡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子撮慨,更是在濱河造成了極大的恐慌竿痰,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砌溺,死亡現(xiàn)場離奇詭異影涉,居然都是意外死亡,警方通過查閱死者的電腦和手機规伐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門蟹倾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人猖闪,你說我怎么就攤上這事鲜棠。” “怎么了培慌?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵豁陆,是天一觀的道長。 經(jīng)常有香客問我吵护,道長盒音,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任馅而,我火速辦了婚禮祥诽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘用爪。我一直安慰自己原押,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布偎血。 她就那樣靜靜地躺著诸衔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颇玷。 梳的紋絲不亂的頭發(fā)上笨农,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機與錄音帖渠,去河邊找鬼谒亦。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的份招。 我是一名探鬼主播切揭,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锁摔!你這毒婦竟也來了廓旬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤谐腰,失蹤者是張志新(化名)和其女友劉穎孕豹,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體十气,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡励背,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了砸西。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叶眉。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖籍胯,靈堂內(nèi)的尸體忽然破棺而出竟闪,到底是詐尸還是另有隱情,我是刑警寧澤杖狼,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布炼蛤,位于F島的核電站,受9級特大地震影響蝶涩,放射性物質(zhì)發(fā)生泄漏理朋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一绿聘、第九天 我趴在偏房一處隱蔽的房頂上張望嗽上。 院中可真熱鬧,春花似錦熄攘、人聲如沸兽愤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浅萧。三九已至,卻和暖如春哲思,著一層夾襖步出監(jiān)牢的瞬間洼畅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工棚赔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留帝簇,地道東北人徘郭。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像丧肴,于是被迫代替她去往敵國和親残揉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 一.Java中的ThreadPoolExecutor類 java.uitl.concurrent.ThreadPo...
    誰在烽煙彼岸閱讀 647評論 0 0
  • 【JAVA 線程】 線程 進程:是一個正在執(zhí)行中的程序闪湾。每一個進程執(zhí)行都有一個執(zhí)行順序冲甘。該順序是一個執(zhí)行路徑,或者...
    Rtia閱讀 2,771評論 2 20
  • 前段時間遇到這樣一個問題途样,有人問微信朋友圈的上傳圖片的功能怎么做才能讓用戶的等待時間較短,比如說一下上傳9張圖片,...
    加油碼農(nóng)閱讀 1,204評論 0 2
  • 轉(zhuǎn)自http://www.cnblogs.com/dolphin0520/p/3932921.html Java并...
    Allen_cyn閱讀 1,906評論 0 4
  • 從HR的崗位轉(zhuǎn)到PM的崗位上有大半年了濒憋。雖然人力工作不是日常工作的重點何暇,但是始終沒有離開這個圈子。我覺得人...
    XuYing_6e2e閱讀 95評論 0 0