併發模型第貳講 accept thread

2021-10-14 11:17:03 字數 3258 閱讀 8569

參考今天總結下乙個併發模型,利用執行緒來達到併發的效果。從某種方面來說,現在的作業系統給我們提供了兩種方式來進行併發任務的執行,一種是程序,另一種是執行緒。 相對於前者來說,執行緒要更輕。所謂更輕,指的是執行緒的建立、銷毀以及切換比起程序來要快速些。

這裡介紹accept+thread的併發模型方式。

伺服器端的主要**如下:

主要的框架**:

#include

"com.h"

#include

"lib.h"

#include

#include

"str_echo.h"

#define listenq 1024

intmain

(int argc,

char

**ar**)

bzero

(&servaddr,

sizeof

(servaddr));

servaddr.sin_family=af_inet;

servaddr.sin_addr.s_addr=

htonl

(inaddr_any)

; servaddr.sin_port=

htons

(serv_port)

;//bindif(

bind

(listenfd,

(struct sockaddr*

)&servaddr,

sizeof

(servaddr)

)<0)

//listenif(

(listen

(listenfd,listenq)

)<0)

pthread_t t_id;

while(1

)printf

(" in server main: conndfd is %d\n"

,connfd)

;int ret =

pthread_create

(&t_id,

null,(

void

*) doit,

(void

*) connfd)

;//建立執行緒 //???傳遞引數可能不安全

if(ret !=0)

// pthread_join(t_id,null); //阻塞等待執行緒結束

}return0;

}

具體的業務邏輯**

#include

"com.h"

#include

"lib.h"

#include

void

str_echo

(int sockfd)

if(n<

0&& errno == eintr)

else

if(n<0)

elseif(

0== n)}}

void

*doit

(void

*arg)

注意上述**借用了unp中的例子,有很多io函式來自unp,篇幅所限,這裡沒有全部貼出。

同樣,這裡先解決幾個遇到有關核心的小問題,最後在對這種併發模型做乙個小總結。

(1)、有關訊號處理的問題,即如果程序(或者)執行緒處在阻塞睡眠之中,訊號發生了,這時候怎麼辦?

如果把執行緒或者程序看成正常的執行流的話,訊號(有的也稱為軟體中斷)是打斷這種正常執行流的一種機制。它通常是非同步的,也就是說程序預先不知道何時這種情況會發生。

如果程序正處在正常的執行狀態,那麼訊號來了(未被mask),ok,程序會轉去執行訊號處理,處理完了之後再回來(和中斷處理類似)。

如果程序正處於阻塞狀態(比如說正阻塞等待accept上),這個時候發生了訊號事件,那麼這個時候怎麼辦呢?

你可能對這個不屑一顧,那就和上面的一樣啊,先去進行訊號處理,處理完了接著阻塞唄。

enen…

事是這麼個事,但是如果要深究一下的話,還有有些東西的:

程序如果處在阻塞中,那麼它是處於阻塞佇列中的,一般情況下,阻塞佇列裡的程序是不會被系統排程到cpu上執行的(除非它等待的情況發生了,比如說阻塞在accept上的程序發現有連線到來就會重新加入就緒佇列。 這是基本的作業系統常識,這裡就不說了)。 現在訊號來了,為了執行訊號處理函式,作業系統不得不把原本應該阻塞的程序排程到cpu上進行執行。

現在,問題來了,執行完訊號處理函式,程序該怎麼辦? 是繼續回到阻塞佇列,還是接著往下執行? 如果要是繼續往下執行的話,原本阻塞的事件還沒來呢(從某種程度來說,程序是被「非期待」的事件所喚醒的)?

現在很多作業系統核心,都採用了前者,又核心把程序繼續放入到阻塞佇列,就像什麼事都沒發生過一樣(實際上執行了訊號處理)。 當然也有一些核心會繼續往下執行,這個時候如果想重新回到阻塞佇列,就必須由上層使用者進行訊號判斷,然後在乙個迴圈裡手動重新呼叫阻塞函式(重新加入阻塞佇列中)。

中訊號處理這一節有比較詳細的描述,可以參考。

(2)、有關執行緒殭屍的討論。

在建立執行緒的過程中,有關於乙個執行緒分離的概念。 新建立的執行緒,一般來說會使用pthread_detach() 函式,自行分離(或者主線程主動呼叫 pthread_join()也可以),這麼做的目的是為了讓執行緒退出的時候能夠「完整的dead」,而不會形成一種「半死不活」的「殭屍」狀態。,有的說法叫做「殭屍執行緒」。

上述操作和程序中所做的差不多, 但是我在做實驗的時候,沒有像程序那樣,確切的觀察到「殭屍執行緒」。

如上文所示,使用命令

top -hp
然後在客戶端終止乙個連線,按理說如果在程式中沒有detach, 會產生殭屍執行緒,但是上面沒有顯示出來。 這個我也沒搞太清楚,有小夥伴了解的,希望可以不吝賜教。

有些說法把這種模型稱作thread-per-connection, 相對於上乙個accept+fork 模型來說,執行緒的開銷比較小。但是相對來說還是不太適合於短連線(建立執行緒的開銷和短連線開銷差不多)。 然而和上篇類似, 這兩種方案都受到執行緒數量(或者程序數量)的影響,如果太多的話,作業系統吃不消的。

、unix 網路程式設計(卷1)

、殭屍執行緒

、 linux多執行緒模型

、linux程序、執行緒模型,lwp,pthread_self()

第2講 略論數學模型方法

1 數學模型的意義 數學模型方法 mathematical modelling method 簡稱mm方法,它不僅是處理數學理論問題的一種經典方法,而且也是處理科技領域中各種實際問題的一般數學方法。特別,現代電子計算機的廣泛應用和科學技術的數學化趨勢,使得mm方法已經非常廣泛地應用於自然科學 工程技...

業務分析(CBAP)第01講 核心概念模型

說起cbap大家可能並不熟悉,但是業務分析或需求分析的工作相信大家肯定不陌生。cbap是國際業務分析師協會 iiba 的高階認證,與之類似的是美國專案管理協會 pmi 的pba。對於business analysis ba 有翻譯為商業分析 業務分析或者需求分析,根據不同的需要可能會有所不同,在本文...

Hive 併發模型

併發支援 是資料庫的必須,而且他們的使用案例很好懂。至少,我們要盡可能支援併發讀和寫。新增幾個發現當前已經鎖定的鎖,是有用的。這裡沒有乙個直接的需求新增乙個api顯式獲取鎖,所以,所有鎖都是隱式獲取的。hive定義一下模式的鎖 注意不需要意向鎖 見名知意,多個共享鎖可以同時獲取,而排他鎖會阻塞其他鎖...