2018-11-06
進(jìn)程通信方法:
套接字socket
a、使用socket通信的方式實(shí)現(xiàn)起來簡單,可以使用因特網(wǎng)域和UNIX域來實(shí)現(xiàn),使用因特網(wǎng)域可以實(shí)現(xiàn)不同主機(jī)之間的進(jìn)出通信。
b、該方式自身攜帶同步機(jī)制,不需要額外的方式來輔助實(shí)現(xiàn)同步。
c、隨進(jìn)程持續(xù)。
共享內(nèi)存
a、最快的一種通信方式,多個(gè)進(jìn)程可同時(shí)訪問同一片內(nèi)存空間,相對(duì)其他方式來說具有更少的數(shù)據(jù)拷貝,效率較高。
b、需要結(jié)合信號(hào)燈或其他方式來實(shí)現(xiàn)多個(gè)進(jìn)程間同步,自身不具備同步機(jī)制。
c、隨內(nèi)核持續(xù),相比于隨進(jìn)程持續(xù)生命力更強(qiáng)。
管道
a、較早的一種通信方式,缺點(diǎn)明顯:只能用于有親緣關(guān)系進(jìn)程之間的通信;只支持單向數(shù)據(jù)流,如果要雙向通信需要多創(chuàng)建一個(gè)管道來實(shí)現(xiàn)。
b、自身具備同步機(jī)制。
c、隨進(jìn)程持續(xù)。
命名管道(FIFO)
a、是有名管道,所以支持沒有親緣關(guān)系的進(jìn)程通信。和共享內(nèi)存類似,提供一個(gè)路徑名字將各個(gè)無親緣關(guān)系的進(jìn)程關(guān)聯(lián)起來。但是也需要?jiǎng)?chuàng)建兩個(gè)描述符來實(shí)現(xiàn)雙向通信。
b、自身具備同步機(jī)制。
c、隨進(jìn)程持續(xù)。
信號(hào)
a、這種通信可攜帶的信息極少。不適合需要經(jīng)常攜帶數(shù)據(jù)的通信。
b、不具備同步機(jī)制,類似于中斷,什么時(shí)候產(chǎn)生信號(hào),進(jìn)程是不知道的。
消息隊(duì)列
a、與共享內(nèi)存和FIFO類似,使用一個(gè)路徑名來實(shí)現(xiàn)各個(gè)無親緣關(guān)系進(jìn)程之間的通信。消息隊(duì)列相比于其他方式有很多優(yōu)點(diǎn):它提供有格式的字節(jié)流,減少了開發(fā)人員的工作量;消息具有類型(system V)或優(yōu)先級(jí)(posix)。其他方式都沒有這些優(yōu)點(diǎn)。
b、具備同步機(jī)制。
c、隨內(nèi)核持續(xù)。
線程通信同步機(jī)制
1、鎖機(jī)制
互斥鎖:提供了以排它方式阻止數(shù)據(jù)結(jié)構(gòu)被并發(fā)修改的方法?;コ怄i的作用就是互斥,mutual exclusive,是用來保護(hù)臨界區(qū)(critical section)的。所謂臨界區(qū)就是代碼的一個(gè)區(qū)間,如果兩個(gè)線程同時(shí)執(zhí)行就有可能出問題,所以需要互斥鎖來保護(hù)。
自旋鎖是一種互斥鎖的實(shí)現(xiàn)方式而已,相比一般的互斥鎖會(huì)在等待期間放棄cpu,自旋鎖(spinlock)則是不斷循環(huán)并測試鎖的狀態(tài),這樣就一直占著cpu。
讀寫鎖:允許多個(gè)線程同時(shí)讀共享數(shù)據(jù),而對(duì)寫操作互斥。
條件變量:可以以原子的方式阻塞進(jìn)程,直到某個(gè)特定條件為真為止。對(duì)條件測試是在互斥鎖的保護(hù)下進(jìn)行的。條件變量始終與互斥鎖一起使用。
2、信號(hào)量機(jī)制:包括無名線程信號(hào)量與有名線程信號(hào)量
信號(hào)量(semaphore)是一種更高級(jí)的同步機(jī)制,mutex可以說是semaphore在僅取值0/1時(shí)的特例。Semaphore可以有更多的取值空間,用來實(shí)現(xiàn)更加復(fù)雜的同步,而不單單是線程間互斥。
3、信號(hào)機(jī)制:類似于進(jìn)程間的信號(hào)處理。
協(xié)程
協(xié)程,又稱微線程,纖程。英文名Coroutine。
協(xié)程的概念很早就提出來了,但直到最近幾年才在某些語言(如Lua)中得到廣泛應(yīng)用。
子程序,或者稱為函數(shù),在所有語言中都是層級(jí)調(diào)用,比如A調(diào)用B,B在執(zhí)行過程中又調(diào)用了C,C執(zhí)行完畢返回,B執(zhí)行完畢返回,最后是A執(zhí)行完畢。
所以子程序調(diào)用是通過棧實(shí)現(xiàn)的,一個(gè)線程就是執(zhí)行一個(gè)子程序。子程序調(diào)用總是一個(gè)入口,一次返回,調(diào)用順序是明確的。而協(xié)程的調(diào)用和子程序不同。
協(xié)程看上去也是子程序,但執(zhí)行過程中,在子程序內(nèi)部可中斷,然后轉(zhuǎn)而執(zhí)行別的子程序,在適當(dāng)?shù)臅r(shí)候再返回來接著執(zhí)行。注意,在一個(gè)子程序中中斷,去執(zhí)行其他子程序,不是函數(shù)調(diào)用,有點(diǎn)類似CPU的中斷。
比如子程序A、B:
def A():
print '1'
print '2'
print '3'
def B():
print 'x'
print 'y'
print 'z'
假設(shè)由協(xié)程執(zhí)行,在執(zhí)行A的過程中,可以隨時(shí)中斷,去執(zhí)行B,B也可能在執(zhí)行過程中中斷再去執(zhí)行A,
結(jié)果可能是:
1
2
x
y
3
z
但是在A中是沒有調(diào)用B的,所以協(xié)程的調(diào)用比函數(shù)調(diào)用理解起來要難一些。
看起來A、B的執(zhí)行有點(diǎn)像多線程,但協(xié)程的特點(diǎn)在于是一個(gè)線程執(zhí)行,那和多線程比,協(xié)程有何優(yōu)勢?
最大的優(yōu)勢就是協(xié)程極高的執(zhí)行效率。因?yàn)樽映绦蚯袚Q不是線程切換,而是由程序自身控制,因此,沒有線程切換的開銷,和多線程比,線程數(shù)量越多,協(xié)程的性能優(yōu)勢就越明顯。
第二大優(yōu)勢就是不需要多線程的鎖機(jī)制,因?yàn)橹挥幸粋€(gè)線程,也不存在同時(shí)寫變量沖突,在協(xié)程中控制共享資源不加鎖,只需要判斷狀態(tài)就好了,所以執(zhí)行效率比多線程高很多。
因?yàn)閰f(xié)程是一個(gè)線程執(zhí)行,那怎么利用多核CPU呢?最簡單的方法是多進(jìn)程+協(xié)程,既充分利用多核,又充分發(fā)揮協(xié)程的高效率,可獲得極高的性能。