程序通訊中使用到的函式講解

2021-10-10 00:01:44 字數 4106 閱讀 3081

函式可用於建立乙個管道,以實現程序間的通訊。

pipe函式的定義如下:

#includeint pipe(int fd[2]);
pipe函式定義中的fd引數是乙個大小為2的乙個陣列型別的指標。該函式成功時返回0,並將一對開啟的檔案描述符值填入fd引數指向的陣列。失敗時返回 -1並設定errno。

通過pipe函式建立的這兩個檔案描述符 fd[0] 和 fd[1] 分別構成管道的兩端,往 fd[1] 寫入的資料可以從 fd[0] 讀出。並且 fd[1] 一端只能進行寫操作,fd[0] 一端只能進行讀操作,不能反過來使用。要實現雙向資料傳輸,可以使用兩個管道。

預設情況下,這一對檔案描述符都是阻塞的。此時,如果我們用read系統呼叫來讀取乙個空的管道,則read將被阻塞,知道管道內有資料可讀;如果我們用write系統呼叫往乙個滿的管道中寫資料,則write也將被阻塞,直到管道有足夠的空閒空間可用(read讀取資料後管道中將清除讀走的資料)。當然,使用者可自行將 fd[0] 和 fd[1] 設定為非阻塞的。

如果管道的寫端檔案描述符 fd[1] 的引用計數減少至0,即沒有任何程序需要往管道中寫入資料,則對該管道的讀端檔案描述符 fd[0] 的read操作將返回0(管道內不存在資料的情況),即讀到了檔案結束標記(eof,end of file);反之,如果管道的讀端檔案描述符 fd[0] 的引用計數減少至0,即沒有任何程序需要從管道讀取資料,則針對該管道的寫端檔案描述符 fd[1] 的write操作將失敗,並引發sigpipe訊號(往讀端被關閉的管道或socket連線中寫資料)。

管道內部傳輸的資料是位元組流,這和tcp位元組流的概念相同。但它們又存在細微的差別。應用層程式能往乙個tcp連線中寫入多少位元組的資料,取決於對方接受視窗的大小和本端的擁塞視窗的大小。而管道的話本身擁有乙個容量限制,它規定如果管道的寫端應用程式不將管道中資料讀走的話,該管道最多還能被寫入多少位元組的資料。管道容量的大小預設是65536位元組。我們也可以使用fcntl函式來修改管道容量。

sprintf函式的格式:

int sprintf( char *buffer, const char *format [, argument,...] );
除了前兩個引數固定外,可選引數可以是任意個。buffer是字元陣列名;format是格式化字串。

sprintf的功能和printf一樣,只不過是printf是將內容按照格式輸出到標準輸出,而sprintf是將內容輸出到

指定的目標buffer。

#include

<

signal.h

>

intsigaction

(int

signum

,const

struct

sigaction

*act

,struct

sigaction

*oldact))

;

sigaction函式用於改變程序接收到特定訊號後的行為。該函式的第乙個引數為訊號的值,可以為除sigkill及sigstop外的任何乙個特定有效的訊號(為這兩個訊號定義自己的處理函式,將導致訊號安裝錯誤)。第二個引數是指向結構sigaction的乙個例項的指標,在結構sigaction的例項中,指定了對特定訊號的處理,可以為空,程序會以預設方式對訊號處理;第三個引數oldact指向的物件用來儲存原來對相應訊號的處理,可指定oldact為null。如果把第

二、第三個引數都設為null,那麼該函式可用於檢查訊號的有效性。

第二個引數最為重要,其中包含了對指定訊號的處理、訊號所傳遞的資訊、訊號處理函式執行過程中應遮蔽掉哪些函式等等。

sigaction結構定義如下:

struct

sigaction

_usigset_t

sa_mask;

unsigned

long

sa_flags;//

void(*

sa_restorer)(

void);

}

其中,sa_restorer,已過時,posix不支援它,不應再被使用。

1、聯合資料結構中的兩個元素_sa_handler以及*_sa_sigaction指定訊號關聯函式,即使用者指定的訊號處理函式。除了可以是使用者自定義的處理函式外,還可以為sig_dfl(採用預設的處理方式),也可以為sig_ign(忽略訊號)。

2、由_sa_handler指定的處理函式只有乙個引數,即訊號值,所以訊號不能傳遞除訊號值之外的任何資訊;由_sa_sigaction是指定的訊號處理函式帶有三個引數,是為實時訊號而設的(當然同樣支援非實時訊號),它指定乙個3引數訊號處理函式。第乙個引數為訊號值,第三個引數沒有使用(posix沒有規範使用該引數的標準),第二個引數是指向siginfo_t結構的指標,結構中包含訊號攜帶的資料值,引數所指向的結構如下:

typedef

struct

siginfo_t

;

siginfo_t結構中的聯合資料成員確保該結構適應所有的訊號,比如對於實時訊號來說,則實際採用下面的結構形式(對於實時訊號的解釋可以自行搜尋,linux中打羽sigtmin的訊號認為是可靠訊號,即時實訊號):

typedef

struct

siginfo

結構的第四個域同樣為乙個聯合資料結構:

union

si**al

採用聯合資料結構,說明siginfo_t結構中的si_value要麼持有乙個4位元組的整數值,要麼持有乙個指標,這就構成了與訊號相關的資料。在訊號的處理函式中,包含這樣的訊號相關資料指標,但沒有規定具體如何對這些資料進行操作,操作方法應該由程式開發人員根據具體任務事先約定。

重要:

si**al結構體:系統呼叫sigqueue傳送訊號時,sigqueue的第三個引數就是si**al聯合資料結構,當呼叫sigqueue時,該資料結構中的資料就將拷貝到訊號處理函式的第二個引數中。這樣,在傳送訊號同時,就可以讓訊號傳遞一些附加資訊。訊號可以傳遞資訊對程式開發是非常有意義的。

siginfo_t.si_value與sigqueue(pid_t pid, int sig, const union si**al val)第三個引數關聯即:

所以通過siginfo_t.si_value可以獲得sigqueue(pid_t pid, int sig, const union si**al val)第三個引數傳遞過來的資料。

如:siginfo_t.si_value.sival_int或siginfo_t.si_value.sival_ptr

其實siginfo_t.si_int直接與si**al.sival_int關聯

siginfo_t.si_ptr直接與si**al.sival_ptr關聯,所以通過這種方式也可以獲得sigqueue傳送過來的資料。

3、sa_mask指定在訊號處理程式執行過程中,哪些訊號應當被阻塞。預設情況下當前訊號本身被阻塞,防止訊號的巢狀傳送,除非指定sa_nodefer或者sa_nomask標誌位,處理程式執行完後,被阻塞的訊號開始執行。

注:請注意sa_mask指定的訊號阻塞的前提條件,是在由sigaction()安裝訊號的處理函式執行過程中由sa_mask指定的訊號才被阻塞。

4、sa_flags中包含了許多標誌位,包括剛剛提到的sa_nodefer及sa_nomask標誌位。另乙個比較重要的標誌位是sa_siginfo,當設定了該標誌位時,表示訊號附帶的引數可以被傳遞到訊號處理函式中,因此,應該為sigaction結構中的sa_sigaction指定處理函式,而不應該為sa_handler指定訊號處理函式,否則,設定該標誌變得毫無意義。即使為sa_sigaction指定了訊號處理函式,如果不設定sa_siginfo,訊號處理函式同樣不能得到訊號傳遞過來的資料,在訊號處理函式中對這些資訊的訪問都將導致段錯誤(segmentation fault)。

注:很多文獻在闡述該標誌位時都認為,如果設定了該標誌位,就必須定義三引數訊號處理函式。實際不是這樣的,驗證方法很簡單:自己實現乙個單一引數訊號處理函式,並在程式中設定該標誌位,可以察看程式的執行結果。實際上,可以把該標誌位看成訊號是否傳遞引數的開關,如果設定該位,則傳遞引數;否則,不傳遞引數。

Oracle中使用到的函式

1.字串相關 1 查詢字串 insrt函式 對指定字串進行判斷,判斷其是否含有指定的字元 instr 源字串 目標字串 開始位置 第幾次出現 用於模糊查詢以及判斷包含關係 select code,name,dept,occupation from staff where instr code,001...

socket通訊中select函式的使用和詳解

最近在寫乙個網路通訊函式,參考別人的 時對select 函式的使用存有疑惑,不太確定具體的使用方法,何時使用,以及其作用。在網上搜到一篇文章,覺得介紹的不錯,收藏學習。先自我總結一下。select函式的作用 select 在socket程式設計中還是比較重要的,可是對於初學socket的人來說都不太...

socket通訊中select函式的使用和詳解

最近在寫乙個網路通訊函式,參考別人的 時對select 函式的使用存有疑惑,不太確定具體的使用方法,何時使用,以及其作用。在網上搜到一篇文章,覺得介紹的不錯,收藏學習。先自我總結一下。select函式的作用 select 在socket程式設計中還是比較重要的,可是對於初學socket的人來說都不太...