Linux 下實現asynchronou notification

今天看到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;
    }
}
相關文章
相關標籤/搜索