IO多路轉接模型select 函式

2021-09-22 08:15:25 字數 3934 閱讀 6744

簡單版通訊——一端輪流說一句

實現讀寫同步:

1.管道是半雙工的,要想實現雙向通訊,需要設定兩條管道

2.當寫端沒寫或是管道內緩衝區資料為空,那麼讀端讀資料會發生阻塞;

當寫端斷開,讀端讀取管道會返回零,會一直while(1)迴圈,需要ctrl+c結束

寫端是指給管道內寫入資料

讀端是指從管道內讀取資料

3.管道的緩衝是4k大小,標準輸入大於4k,將會發***

對於1號管道,由於b端先開啟寫端,所以b先說話 a端 開啟1號管道的讀端 開啟2號管道的寫端

b端 開啟1號管道的寫端 開啟2號管道的讀端 這兩個假如順序錯誤,則會產生死鎖,互相等待 比如說,開啟不同管道的任意一端或者開啟同一管道的同一端,會產生死鎖

a端的**如下:

#include #include #include #include #include #include //a端

int main(int argc, char* ar**)

int fd1, fd2;

//必須o_rdonly

//開啟1號管道的讀端

fd1 = open(ar**[1], o_rdonly);

if (-1 == fd1)

//必須o_wronly

//開啟2號管道的寫端

fd2 = open(ar**[2], o_wronly);

if (-1 == fd2)

printf("i am a");

char buf[128] = ;

while(1)

return 0;

}

b端的**如下:

#include #include #include #include #include #include //b端

int main(int argc, char* ar**)

int fd1, fd2;

//必須o_wronly

//開啟1號管道的寫端

fd1 = open(ar**[1], o_wronly);

if (-1 == fd1)

//必須o_rdonly

//開啟2號管道的讀端

fd2 = open(ar**[2], o_rdonly);

if (-1 == fd2)

printf("i am b");

char buf[128] = ;

while(1)

return 0;

}

mkfifo 1.pipe

mkfifo 2.pipe

gcc a.c -o a

gcc b.c -o b

./a 1.pipe 2.pipe

./b 1.pipe 2.pipe

缺點是只能實現一端只能輪流說一句話

正常版通訊select()函式——io多路轉接模型

檔案描述符具有阻塞屬性的是標準輸入描述符0和讀描述符fdr

讓select監控檔案描述符,0號描述符和fdr描述符,一旦觀察到buf區裡面有資料,馬上通知,若0號描述符可讀,則寫出,返回;若fdr可讀,則寫出,返回;若兩個都不可讀,則阻塞。

select函式的相關介面

#include #include int select(int maxfd, fd_set* readset, fd_set* writeset, fd_set* exceptionset,

const struct timeval* timeout);

//maxfd:最大的檔案描述符(其值應該為最大的檔案描述符字+1)

//readset:核心讀操作的描述符字集合

//writeset:核心寫操作的描述符字集合

//exceptionset:核心異常操作的描述符字集合

//timeout:等待描述符就緒需要多少時間,null代表永遠等下去,乙個固定值代表固定時間,

//0代表根本不等待,檢查描述字之後立即返回。

//其中readset,writeset,exceptionset都是fd_set集合

void fd_zero(fd_set* fdset);//將所有fd清零

void fd_set(int fd, fd_set* fdset);//增加乙個fd*

void fd_clr(int fd, fd_set* fdset);//刪除乙個fd*

int fd_isset(int fd, fd_set* fdset);//判斷乙個fd,是否有設定

先定義乙個集合陣列,用於儲存要監控的fd,再傳陣列的指標(對陣列取位址)

fd_set rdset;

fd_zero(&rdset);//每次迴圈都需要清零

//告訴select函式要監視的檔案描述符

fd_set(0, &rdset);//每次迴圈都需要監視

fd_set(fdr, &rdset);//每次迴圈都需要監視

//設定超時時間,若超過,還沒有描述符就緒可讀,則返回;若同時可讀,也返回

//傳入傳出引數rdset

select裡面對rdset做的操作

fd_set tmpset

memcpy(&tmpset, &rdset, sizeof(fd_set));

//記憶體拷貝可以拷貝任意格式的資料

fd_zero(&rdset);//清空

進行輪詢:int fd_isset(int fd, fd_set* fdset);

//迴圈呼叫該函式測試描述符函式集

b端**如下:

#include #include #include #include #include #include #include #include //管道的寫端

int main(int argc,char* ar**)

int fdw,fdr;

fdw = open(ar**[1], o_wronly);//必須o_wronly

if(-1 == fdw)

fdr = open(ar**[2], o_rdonly);//必須o_rdonly

if(-1 == fdr)

printf("i am b\n");

char buf[128];

int ret;

fd_set rdset;

while(1)

write(fdw, buf, strlen(buf)-1);//寫到1號管道

}if(fd_isset(fdr, &rdset))//判斷fdr是否可讀

printf("%s\n", buf);

}} }

return 0;

}

a端**如下

#include #include #include #include #include #include #include #include //管道的讀端

int main(int argc, char* ar**)

int fdr, fdw;

fdr = open(ar**[1], o_rdonly);//必須o_rdonly

if(-1 == fdr)

fdw = open(ar**[2], o_wronly);//必須o_wronly

if(-1 == fdw)

printf("i am o_a\n");

char buf[128] = ;

fd_set rdset;

int ret;

while(1)

printf("%s\n", buf);

}if (fd_isset(0, &rdset))

else

}} }

return 0;

}

I O多路轉接(select

一.基本概念 二.函式原型 includeint select int nfds,fd set readfds,fd set writefds,fd set exceptions,struct timeval timeout fd set 介面 void fd clr int fd,fd set s...

select多路IO轉接

void fd zero fd set set 清空乙個檔案描述符集合。fd set rset fd zero rset void fd set int fd,fd set set 將待監聽的檔案描述符,新增到監聽集合中 fd set 3,rset fd set 5,rset fd set 6,rs...

IO 多路轉接 select

select多路io轉接 原理 借助核心,select來監聽,客戶端連線 資料通訊事件 void fd clr int fd,fd set set 將乙個檔案描述符從監聽集合中 移除 fd clr 4,rset int fd isset int fd,fd set set 判斷乙個檔案描述符是否在監...