国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > Linux學(xué)習(xí) > linux入門 > Linux串口編程select詳解

Linux串口編程select詳解 時(shí)間:2018-08-16      來源:未知

今天要和大家分享的Linux學(xué)習(xí)知識點(diǎn)是Linux串口編程select。select系統(tǒng)調(diào)用的的用途是:在一段指定的時(shí)間內(nèi),監(jiān)聽用戶感興趣的文件描述符上可讀、可寫和異常等事件。

Linux串口編程select詳解
Linux串口編程select詳解

①select機(jī)制的優(yōu)勢

為什么會(huì)出現(xiàn)select模型?

先看一下下面的這句代碼:

int iResult = recv(s, buffer,1024);

這是用來接收數(shù)據(jù)的,在默認(rèn)的阻塞模式下的套接字里,recv會(huì)阻塞在那里,直到套接字連接上有數(shù)據(jù)可讀,把數(shù)據(jù)讀到buffer里后recv函數(shù)才會(huì)返回,不然就會(huì)一直阻塞在那里。在單線程的程序里出現(xiàn)這種情況會(huì)導(dǎo)致主線程(單線程程序里只有一個(gè)默認(rèn)的主線程)被阻塞,這樣整個(gè)程序被鎖死在這里,如果永 遠(yuǎn)沒數(shù)據(jù)發(fā)送過來,那么程序就會(huì)被永遠(yuǎn)鎖死。這個(gè)問題可以用多線程解決,但是在有多個(gè)套接字連接的情況下,這不是一個(gè)好的選擇,擴(kuò)展性很差。

再看代碼:

int iResult = ioctlsocket(s, FIOBIO, (unsigned long *)&ul);

iResult = recv(s, buffer,1024);

這一次recv的調(diào)用不管套接字連接上有沒有數(shù)據(jù)可以接收都會(huì)馬上返回。原因就在于我們用ioctlsocket把套接字設(shè)置為非阻塞模式了。不過你跟蹤一下就會(huì)發(fā)現(xiàn),在沒有數(shù)據(jù)的情況下,recv確實(shí)是馬上返回了,但是也返回了一個(gè)錯(cuò)誤:WSAEWOULDBLOCK,意思就是請求的操作沒有成功完成。

看到這里很多人可能會(huì)說,那么就重復(fù)調(diào)用recv并檢查返回值,直到成功為止,但是這樣做效率很成問題,開銷太大。

select模型的出現(xiàn)就是為了解決上述問題。

select模型的關(guān)鍵是使用一種有序的方式,對多個(gè)套接字進(jìn)行統(tǒng)一管理與調(diào)度 。

Select模型示意圖

如上所示,用戶首先將需要進(jìn)行IO操作的socket添加到select中,然后阻塞等待select系統(tǒng)調(diào)用返回。當(dāng)數(shù)據(jù)到達(dá)時(shí),socket被激活,select函數(shù)返回。用戶線程正式發(fā)起read請求,讀取數(shù)據(jù)并繼續(xù)執(zhí)行。

從流程上來看,使用select函數(shù)進(jìn)行IO請求和同步阻塞模型沒有太大的區(qū)別,甚至還多了添加監(jiān)視socket,以及調(diào)用select函數(shù)的額外操作,效率更差。但是,使用select以后大的優(yōu)勢是用戶可以在一個(gè)線程內(nèi)同時(shí)處理多個(gè)socket的IO請求。用戶可以注冊多個(gè)socket,然后不斷地調(diào)用select讀取被激活的socket,即可達(dá)到在同一個(gè)線程內(nèi)同時(shí)處理多個(gè)IO請求的目的。而在同步阻塞模型中,必須通過多線程的方式才能達(dá)到這個(gè)目的。

select流程偽代碼如下:

{

select(socket);

while(1)

{

sockets = select();

for(socket in sockets)

{

if(can_read(socket))

{

read(socket, buffer);

process(buffer);

}

}

}

}

②select相關(guān)API介紹與使用

#include #include #include #include int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);

參數(shù)說明:

maxfdp:被監(jiān)聽的文件描述符的總數(shù),它比所有文件描述符集合中的文件描述符的大值大1,因?yàn)槲募枋龇菑?開始計(jì)數(shù)的;

readfds、writefds、exceptset:分別指向可讀、可寫和異常等事件對應(yīng)的描述符集合。

timeout:用于設(shè)置select函數(shù)的超時(shí)時(shí)間,即告訴內(nèi)核select等待多長時(shí)間之后就放棄等待。timeout == NULL 表示等待無限長的時(shí)間

timeval結(jié)構(gòu)體定義如下:

struct timeval

{

long tv_sec; /*秒 */

long tv_usec; /*微秒 */ };

返回值:超時(shí)返回0;失敗返回-1;成功返回大于0的整數(shù),這個(gè)整數(shù)表示就緒描述符的數(shù)目。

以下介紹與select函數(shù)相關(guān)的常見的幾個(gè)宏:

#include int FD_ZERO(int fd, fd_set *fdset); //一個(gè) fd_set類型變量的所有位都設(shè)為 0int FD_CLR(int fd, fd_set *fdset); //清除某個(gè)位時(shí)可以使用int FD_SET(int fd, fd_set *fd_set); //設(shè)置變量的某個(gè)位置位int FD_ISSET(int fd, fd_set *fdset); //測試某個(gè)位是否被置位

select使用范例:

當(dāng)聲明了一個(gè)文件描述符集后,必須用FD_ZERO將所有位置零。之后將我們所感興趣的描述符所對應(yīng)的位置位,操作如下:

fd_set rset; int fd; FD_ZERO(&rset); FD_SET(fd, &rset); FD_SET(stdin, &rset);

然后調(diào)用select函數(shù),擁塞等待文件描述符事件的到來;如果超過設(shè)定的時(shí)間,則不再等待,繼續(xù)往下執(zhí)行。

select(fd+1, &rset, NULL, NULL,NULL);

select返回后,用FD_ISSET測試給定位是否置位:

if(FD_ISSET(fd, &rset)

{

...

//do something

}

下面是一個(gè)簡單的select的使用例子:

#include #include #include #include #include int main(){

fd_set rd; struct timeval tv; int err;

FD_ZERO(&rd);

FD_SET(0,&rd);

tv.tv_sec = 5;

tv.tv_usec = 0;

err = select(1,&rd,NULL,NULL,&tv);

if(err == 0) //超時(shí)

{ printf("select time out!\n");

} else if(err == -1) //失敗

{ printf("fail to select!\n");

} else //成功

{ printf("data is available!\n");

}

return 0;

}

我們運(yùn)行該程序并且隨便輸入一些數(shù)據(jù),程序就提示收到數(shù)據(jù)了。

程序運(yùn)行結(jié)果圖

以上就是Linux串口編程select的相關(guān)知識點(diǎn),更多Linux知識學(xué)習(xí),請關(guān)注Linux系統(tǒng)入門學(xué)習(xí)欄目。

上一篇:十大linux培訓(xùn)機(jī)構(gòu)有哪幾家 linux培訓(xùn)機(jī)構(gòu)排名如何

下一篇:Linux學(xué)習(xí)路線圖『從入門到精通』

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號-5京公海網(wǎng)安備11010802025203號

回到頂部