今天看到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; } }