在編程的過程中,經常會遇到許多阻塞的函數,好像read和網路編程時使用的recv, recvfrom函數都是阻塞的函數,當函數不能成功執行的時候,程式就會一直阻塞在這裡,無法執行下面的代碼。這是就需要用到非阻塞的編程方式,使用selcet函數就可以實現非阻塞編程。
selcet函數是一個輪循函數,即當迴圈詢問檔案節點,可設定逾時時間,逾時時間到了就跳過代碼繼續往下執行。
例子:
fd_set readfd;struct timeval timeout;FD_ZERO(&readfd); //初始化readfdFD_SET(gps_fd, &readfd); //把gps_fd加入readfdtimeout.tv_sec = 3; //設定3秒逾時timeout.tv_usec = 0;j = select(gps_fd+1, &readfd, NULL, NULL, &timeout); //用select對gps_fd進行輪循if( j>0 ){ if( FD_ISSET(gps_fd, &readfd) ){ //如果gps_fd可讀 i = read(gps_fd, buf, SIZE); buf[i] = '\0'; }}select函數有5個參數
第一個是所有檔案節點的最大值加1,如果我有三個檔案節點1、4、6,那第一個參數就為7(6+1)
第二個是可讀檔案節點集,類型為fd_set。通過FD_ZERO(&readfd);初始化節點集;然後通過FD_SET(fd, &readfd);把需要監聽是否可讀的節點加入節點集
第三個是可寫檔案節點集中,類型為fd_set。操作方法和第二個參數一樣。
第四個參數是檢查節點錯誤集。
第五個參數是逾時參數,類型為struct timeval,然後可以設定逾時時間,分別可設定秒timeout.tv_sec和微秒timeout.tv_usec。
然後調用select函數,用FD_ISSET()函數判斷節點是否可讀寫。傳回值不為0表示可讀寫,為0表示不可讀寫。select函數的傳回值為是一個整數,表示有幾個節點可讀寫。