線程
什么是線程
線程芒炼,有時(shí)被稱為輕量級(jí)進(jìn)程(Lightweight Process瘫怜,LWP),是程序執(zhí)行流的最小單元本刽。一個(gè)標(biāo)準(zhǔn)的線程由線程ID鲸湃,當(dāng)前指令[指針])(PC),[寄存器])集合和[堆棧組 成子寓。另外暗挑,線程是進(jìn)程中的一個(gè)實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位别瞭,線程自己不擁有系統(tǒng)資源窿祥,只擁有一點(diǎn)兒在運(yùn)行中必不可少的資源,但它可與同屬一個(gè) 進(jìn)程的其它線程共享進(jìn)程所擁有的全部資源蝙寨。一個(gè)線程可以創(chuàng)建和撤消另一個(gè)線程晒衩,同一進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約墙歪,致使線程 在運(yùn)行中呈現(xiàn)出間斷性听系。線程也有[就緒]、[阻塞]和[運(yùn)行]三種基本狀態(tài)虹菲。就緒狀態(tài)是指線程具備運(yùn)行的所有條件靠胜,邏輯上可以運(yùn)行,在等待處理機(jī);運(yùn)行狀態(tài)是指線程占有處理機(jī)正在運(yùn)行浪漠;阻塞狀態(tài)是指線程在等待一個(gè)事件(如某個(gè)信號(hào)量)陕习,邏輯上不可執(zhí)行。每一個(gè)程序都至少有一個(gè)線程址愿,若程序只有一個(gè)線程该镣,那就是程序本身。
線程是程序中一個(gè)單一的順序控制流程响谓。進(jìn)程內(nèi)一個(gè)相對(duì)獨(dú)立的损合、可調(diào)度的執(zhí)行單元,是系統(tǒng)獨(dú)立調(diào)度和分派CPU的基本單位指[運(yùn)行]中的程序的調(diào)度單位娘纷。在單個(gè)程序中同時(shí)運(yùn)行多個(gè)線程完成不同的工作嫁审,稱為[多線程]。
線程是程序中一個(gè)單一的順序控制流程赖晶。進(jìn)程內(nèi)一個(gè)相對(duì)獨(dú)立的律适、可調(diào)度的執(zhí)行單元,是系統(tǒng)獨(dú)立調(diào)度和分派CPU的基本單位指[運(yùn)行]中的程序的調(diào)度單位遏插。在單個(gè)程序中同時(shí)運(yùn)行多個(gè)線程完成不同的工作擦耀,稱為[多線程]。
python的thread模塊是比較底層的模塊涩堤,python的threading模塊是對(duì)thread做了一些包裝的,可以更加方便的被使用
#coding=utf-8
import time
def saySorry():
for i in range(5):
print("親愛的分瘾,我錯(cuò)了胎围,我能吃飯了嗎?")
time.sleep(1)
def do():
for i in range(5):
print("親愛的德召,我錯(cuò)了白魂,我給你按摩")
time.sleep(1)
if __name__ == "__main__":
saySorry()
saydo()
多線程
#coding=utf-8
import threading
import time
def saySorry():
for i in range(5):
print("親愛的,我錯(cuò)了上岗,我能吃飯了嗎福荸?")
time.sleep(1)
def do():
for i in range(5):
print("親愛的,我錯(cuò)了肴掷,我給你按摩")
time.sleep(1)
if __name__ == "__main__":
td1 = threading.Thread(target=saySorry)
td1.start() #啟動(dòng)線程敬锐,即讓線程開始執(zhí)行
td2 = threading.Thread(target=saySorry)
td2.start() #啟動(dòng)線程,即讓線程開始執(zhí)行
threading.Thread參數(shù)介紹
target:線程執(zhí)行的函數(shù)
name:線程名稱
args:執(zhí)行函數(shù)中需要傳遞的參數(shù)呆瞻,元組類型 另外:注意daemon參數(shù)
如果某個(gè)子線程的daemon屬性為False台夺,主線程結(jié)束時(shí)會(huì)檢測(cè)該子線程是否結(jié)束,如果該子線程還在運(yùn)行痴脾,則主線程會(huì)等待它完成后再退出颤介;
如果某個(gè)子線程的daemon屬性為True,主線程運(yùn)行結(jié)束時(shí)不對(duì)這個(gè)子線程進(jìn)行檢查而直接退出,同時(shí)所有daemon值為True的子線程將隨主線程一起結(jié)束滚朵,而不論是否運(yùn)行完成冤灾。
屬性daemon的值默認(rèn)為False,如果需要修改辕近,必須在調(diào)用start()方法啟動(dòng)線程之前進(jìn)行設(shè)置
可以明顯看出使用了多線程并發(fā)的操作韵吨,花費(fèi)時(shí)間要短很多 2.當(dāng)調(diào)用start()時(shí),才會(huì)真正的創(chuàng)建線程亏推,并且開始執(zhí)行
進(jìn)程
什么是進(jìn)程
)是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動(dòng)学赛,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,是[操作系統(tǒng)]結(jié)構(gòu)的基礎(chǔ)吞杭。在早期面向進(jìn)程設(shè)計(jì)的計(jì)算機(jī)結(jié)構(gòu)中盏浇,進(jìn)程是程序的基本執(zhí)行實(shí)體;在當(dāng)代面向線程設(shè)計(jì)的計(jì)算機(jī)結(jié)構(gòu)中芽狗,進(jìn)程是線程的容器绢掰。程序是指令、數(shù)據(jù)及其組織形式的描述童擎,進(jìn)程是程序的實(shí)體滴劲。
進(jìn)程是一個(gè)具有獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次運(yùn)行活動(dòng)。它可以申請(qǐng)和擁有系統(tǒng)資源顾复,是一個(gè)動(dòng)態(tài)的概念班挖,是一個(gè)活動(dòng)的實(shí)體。它不只是程序的[代碼]芯砸,還包括當(dāng)前的活動(dòng)萧芙,通過(guò)[程序計(jì)數(shù)器]的值和處理[寄存器]的內(nèi)容來(lái)表示。
進(jìn)程的概念主要有兩點(diǎn):第一假丧,進(jìn)程是一個(gè)實(shí)體双揪。每一個(gè)進(jìn)程都有它自己的地址空間,一般情況下包帚,包括[文本]區(qū)域渔期、數(shù)據(jù)區(qū)域(data region)和[堆棧](stack region)。文本區(qū)域存儲(chǔ)處理器執(zhí)行的代碼渴邦;數(shù)據(jù)區(qū)域存儲(chǔ)變量和進(jìn)程執(zhí)行期間使用的動(dòng)態(tài)分配的內(nèi)存疯趟;堆棧區(qū)域存儲(chǔ)著活動(dòng)過(guò)程調(diào)用的指令和本地變量。第二谋梭,進(jìn)程是一個(gè)“執(zhí)行中的程序”迅办。程序是一個(gè)沒(méi)有生命的實(shí)體,只有[處理]器賦予程序生命時(shí)(操作系統(tǒng)執(zhí)行之)章蚣,它才能成為一個(gè)活動(dòng)的實(shí)體站欺,我們稱其為[進(jìn)程]姨夹。
進(jìn)程的狀態(tài)
工作中,任務(wù)數(shù)往往大于cpu的核數(shù)矾策,即一定有一些任務(wù)正在執(zhí)行磷账,而另外一些任務(wù)在等待cpu進(jìn)行執(zhí)行,因此導(dǎo)致了有了不同的狀態(tài)
就緒態(tài):運(yùn)行的條件都已經(jīng)慢去贾虽,正在等在cpu執(zhí)行
執(zhí)行態(tài):cpu正在執(zhí)行其功能
等待態(tài):等待某些條件滿足逃糟,例如一個(gè)程序sleep了,此時(shí)就處于等待態(tài)
進(jìn)程的創(chuàng)建-multiprocessing
進(jìn)程池
當(dāng)需要?jiǎng)?chuàng)建的子進(jìn)程數(shù)量不多時(shí)蓬豁,可以直接利用multiprocessing中的Process動(dòng)態(tài)成生多個(gè)進(jìn)程绰咽,但如果是上百甚至上千個(gè)目標(biāo),手動(dòng)的去創(chuàng)建進(jìn)程的工作量巨大地粪,此時(shí)就可以用到multiprocessing模塊提供的Pool方法取募。
初始化Pool時(shí),可以指定一個(gè)最大進(jìn)程數(shù)蟆技,當(dāng)有新的請(qǐng)求提交到Pool中時(shí)玩敏,如果池還沒(méi)有滿,那么就會(huì)創(chuàng)建一個(gè)新的進(jìn)程用來(lái)執(zhí)行該請(qǐng)求质礼;但如果池中的進(jìn)程數(shù)已經(jīng)達(dá)到指定的最大值旺聚,那么該請(qǐng)求就會(huì)等待,直到池中有進(jìn)程結(jié)束眶蕉,才會(huì)用之前的進(jìn)程來(lái)執(zhí)行新的任務(wù)砰粹,請(qǐng)看下面的實(shí)例:
進(jìn)程與線程的對(duì)比:
一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程.
線程的劃分尺度小于進(jìn)程(資源比進(jìn)程少),使得多線程程序的并發(fā)性高
進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元造挽,而多個(gè)線程共享內(nèi)存伸眶,從而極大地提高了程序的運(yùn)行效率
線線程不能夠獨(dú)立執(zhí)行,必須依存在進(jìn)程中
優(yōu)缺點(diǎn)
線程和進(jìn)程在使用上各有優(yōu)缺點(diǎn):線程執(zhí)行開銷小刽宪,但不利于資源的管理和保護(hù);而進(jìn)程正相反界酒。
協(xié)程圣拄、
一個(gè)程序可以包含多個(gè)協(xié)程,可以對(duì)比與一個(gè)進(jìn)程包含多個(gè)線程毁欣,因而下面我們來(lái)比較協(xié)程和線程庇谆。我們知道多個(gè)線程相對(duì)獨(dú)立,有自己的上下文凭疮,切換受系統(tǒng)控制饭耳;而協(xié)程也相對(duì)獨(dú)立,有自己的上下文执解,但是其切換由自己控制寞肖,由當(dāng)前協(xié)程切換到其他協(xié)程由當(dāng)前協(xié)程來(lái)控制。