Python3簡單實(shí)現(xiàn)多任務(wù)(線程/協(xié)程篇)

寫在前面

  • 上一篇文章[Python3簡單實(shí)現(xiàn)多任務(wù)(多進(jìn)程篇)]已經(jīng)介紹了python多進(jìn)程實(shí)現(xiàn)多任務(wù)的簡單實(shí)現(xiàn)方法;
  • 這次講一講python創(chuàng)建多任務(wù)另外兩種常見的方式:
  • 協(xié)程和線程


線程多任務(wù)實(shí)現(xiàn)1:直接使用Thread創(chuàng)建線程

from threading import Thread
import threading
import os
import time
import random

def not_know(thread_num):
    
    print("第%d線程吟唱:不知天上宮闕"%(thread_num))
    time.sleep(random.random())
    print("第%d線程吟唱:今夕是何年"%(thread_num))
    time.sleep(random.random())
    print("第%d號線程:<吟唱古詩>任務(wù)結(jié)束..."%(thread_num))

def main():
    for i in range(1, 6):
        num = len(threading.enumerate())
        print("當(dāng)前線程數(shù)為:%d"%num)
        t = Thread(target=not_know, args=(i,))
        t.start()
        time.sleep(0.8)

if __name__ == "__main__":
    print("--->主函數(shù)開始運(yùn)行<---")
    main()
    print("--->主函數(shù)運(yùn)行完畢<---")

線程多任務(wù)實(shí)現(xiàn)2:定義類繼承threading.Thread,然后重寫run方法(run方法相當(dāng)于功能函數(shù))

from threading import Thread
import threading
import os
import random
import time

class the_cosmetic(threading.Thread):
    def __init__(self, num):
        self.num = num
        # 一定要記得調(diào)用父類構(gòu)造方法
        threading.Thread.__init__(self)

    def run(self):
        print("-->第%d線程開始執(zhí)行<--"%self.num)
        time.sleep(random.random())
        print("%d最有效的化妝品是什么?"%self.num)
        time.sleep(random.random())
        print("%dPhotoshop是最好的化妝品!"%self.num)
        time.sleep(random.random())
        print("-->第%d線程執(zhí)行完畢<--"%self.num)

def main():
    print("-------->開始創(chuàng)建線程<--------")

    for i in range(1, 6):
        t = the_cosmetic(i)
        t.start()

    print("-------->線程創(chuàng)建完畢<--------")

if __name__ == "__main__":
    main()

協(xié)程多任務(wù)實(shí)現(xiàn)1:gevent(使用簡單,推薦!需要pip安裝gevent)

sudo pip3 install gevent

import time
import random
import gevent
from gevent import monkey

monkey.patch_all()

def peach(name):
    for i in range(1, 6):
        start_time = time.time()
        time.sleep(random.random())
        end_time = time.time()
        # 使用 round() 控制小數(shù)點(diǎn)位數(shù)!
        print("%s產(chǎn)出第%s個(gè)桃子,耗時(shí)%s"%(name, i, round(end_time - start_time, 2)))

def apple(name):
    for i in range(1, 8):
        start_time = time.time()
        time.sleep(random.random())
        end_time = time.time()
        print("%s產(chǎn)出第%s個(gè)蘋果,耗時(shí)%s"%(name, i, round(end_time - start_time, 2)))

def main():
    # 注意:下面的語句,沒有等號! 沒有等號! 沒有等號!
    gevent.joinall([
        gevent.spawn(peach,"LI"),
        gevent.spawn(apple,"HO"),
        ])

if __name__ == "__main__":
    main()

協(xié)程多任務(wù)實(shí)現(xiàn)2:yield實(shí)現(xiàn)協(xié)程(yield最底層,最靈活,是python自帶的模塊)

import time

def to_activate():
    yield
    print("吃早飯")
    print("讀文檔")
    yield
    print("吃中午飯")
    print("寫程序")
    yield
    print("吃晚飯")
    print("解bug")

def to_sleep():
    yield
    print("午睡")
    yield
    print("晚休")

def main():
    print("程序員的一天")
    activate = to_activate()
    sleep = to_sleep()

    # 利用yield開始在兩個(gè)函數(shù)間跳轉(zhuǎn)
    next(activate)
    next(sleep)
    next(activate)
    next(sleep)
    next(activate)

    print("程序員的一天結(jié)束了")



if __name__ == "__main__":
    main()


協(xié)程多任務(wù)實(shí)現(xiàn)3:greenlet實(shí)現(xiàn)協(xié)程(模塊須通過pip單獨(dú)安裝,個(gè)人感覺這個(gè)模塊封裝的并不夠好,所以放到最后,僅供了解)

sudo pip3 install greenlet


import time
from greenlet import greenlet

activate = None
sleep = None

def to_activate():
    print("吃早飯")
    print("讀文檔")
    sleep.switch()
    print("吃中午飯")
    print("寫程序")
    print("吃晚飯")
    print("解bug")

def to_sleep():
    print("午睡")
    activate.switch()
    print("晚休")

def main():
    global activate
    global sleep
    print("程序員的一天")
    activate = greenlet(to_activate)
    sleep = greenlet(to_sleep)

    #從activate開始執(zhí)行
    activate.switch()
    print("程序員的一天結(jié)束了")



if __name__ == "__main__":
    main()

小結(jié)

  • 線程與進(jìn)程相比,占用資源更少,但線程依賴于進(jìn)程,一個(gè)進(jìn)程可以有多個(gè)線程,進(jìn)程完成任務(wù)依賴于內(nèi)部的線程;
  • 協(xié)程解決了線程之間爭用資源引發(fā)的資源浪費(fèi),所以協(xié)程比線程占用的資源更少.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吕嘀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陌兑,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)奢驯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來次绘,“玉大人瘪阁,你說我怎么就攤上這事∮寿耍” “怎么了管跺?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長禾进。 經(jīng)常有香客問我豁跑,道長,這世上最難降的妖魔是什么泻云? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任艇拍,我火速辦了婚禮,結(jié)果婚禮上宠纯,老公的妹妹穿的比我還像新娘卸夕。我一直安慰自己,他們只是感情好婆瓜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布快集。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碍讨。 梳的紋絲不亂的頭發(fā)上治力,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機(jī)與錄音勃黍,去河邊找鬼宵统。 笑死,一個(gè)胖子當(dāng)著我的面吹牛覆获,可吹牛的內(nèi)容都是我干的马澈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼弄息,長吁一口氣:“原來是場噩夢啊……” “哼痊班!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起摹量,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涤伐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后缨称,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凝果,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年睦尽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了器净。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡当凡,死狀恐怖山害,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沿量,我是刑警寧澤浪慌,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站朴则,受9級特大地震影響眷射,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜佛掖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一妖碉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芥被,春花似錦欧宜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽席镀。三九已至,卻和暖如春夏漱,著一層夾襖步出監(jiān)牢的瞬間豪诲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工挂绰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屎篱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓葵蒂,卻偏偏與公主長得像交播,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子践付,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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