今天看到LLD3上的chapter6中的asynchronous notification這一節,想起了我以前的一個帖子。socket
http://www.oschina.net/question/158589_26587async
那個時候,我其實就是想實現這種被動的通知,而不是主動的輪詢。參考書上的例子,能夠簡單實現以下。this
其原理,就是利用信號來實現一個event-driven的控制。.net
值得一提的是,並非全部文件都支持asynchronous notification,一般socket和tty是支持的。code
另外,若是想讓本身的驅動支持asynchronous notification,必需要本身實現。方法參見LLD3 chapter6.進程
最重要的是以下幾句話。get
fcntl(STDIN_FILENO, F_SETOWN, getpid()); fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | FASYNC); //第一句,將stdio的owner設置爲當前進程 //第二句,通知該文件的驅動,告訴它若是有數據可用,那麼就通知這個file的owner //完整示例程序以下。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <fcntl.h> int gotdata=0; void sighandler(int signo) { if (signo==SIGIO) gotdata++; return; } char buffer[4096]; int main(int argc, char **argv) { int count; struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = sighandler; action.sa_flags = 0; sigaction(SIGIO, &action, NULL); fcntl(STDIN_FILENO, F_SETOWN, getpid()); fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | FASYNC); while(1) { /* this only returns if a signal arrives */ sleep(86400); /* one day */ if (!gotdata) continue; count=read(0, buffer, 4096); /* buggy: if avail data is more than 4kbytes... */ write(1,buffer,count); gotdata=0; } }