异步I/O初认识

问题:编一个小程序实现:主循环在调用sleep(),当用户通过键盘输入一个特定的字符时主循环退出,用信号SIGIO来实现。
先了解SIGIO信号:它是一个异步I/O信号,这个信号可以发送给已经注册了该信号的进程,即当某一进程有一个I/O口(一般就是对于文件描述符),如果对这个I/O口有I/O操作,就会发送SIGIO信号给该进程,进程就可根据信号进行自己的操作。
注册信号的步骤:
s1. 对文件描述符调用fcntl函数,设置O_NONBLOCK和O_ASYNC(只能对终端和网络的文件描述符使用)属性;
fcntl(fd, F_SETFL, old | O_NONBLOCK | O_ASYNC)
s2. 对文件描述符设置SIGIO、SIGURG信号所通知的进程,一般是调用进程本身;
fcntl(fd, F_SETOWN, getpid())
s3. 编写signal handler函数,并使用signal或sigaction函数注册。
所以我们就可以很快的写出代码:

#include        <curses.h>
#include        <signal.h>
#include        <fcntl.h>
#include        <string.h>
#include        <stdlib.h>

int done ;
main()
{
        void actfun(int);
        done = 1;
        struct sigaction sig_act;
            int fl = 0;
                fflush(stdin);
                fflush(stdout);
                fl = fcntl(STDIN_FILENO, F_GETFL, 0);
                fcntl(STDIN_FILENO, F_SETFL, fl | O_NONBLOCK | O_ASYNC );
                fcntl(STDIN_FILENO, F_SETOWN, getpid());
                sigemptyset(&sig_act.sa_mask);
                sig_act.sa_flags = 0;
                sig_act.sa_handler = actfun;
                sigaction(SIGIO, &sig_act, NULL);
          while(done){
                sleep(1);
                if(done == 0)
                        break;
          }
}

void actfun(int signum)
{
        char buf[10];
        read(0,buf,10);
        if(strncmp(buf,"q",1) == 0)
        {
                done = 0;
        }
}

在这里我们也可以用aio_read来实现

int aio_read( struct aiocb *aiocbp );

struct aiocb结构体

struct aiocb { 
  int aio_fildes;        // File Descriptor
  int aio_lio_opcode;    // Valid only for lio_listio (r/w/nop)
  volatile void *aio_buf; // Data Buffer
  size_t aio_nbytes;      // Number of Bytes in Data Buffer
  struct sigevent aio_sigevent; // Notification Structure
  off_t aio_offset;
 };

aio_fildes 字段表示被打开用来读或者写的文件描述符,读或写操作从aio_offset指定的偏移量开始。读操作会复制到aio_buf,写操作会从aio_buf复制出来。aio_nbytes表示要读或者写的字节数。
其中aio_sigevent字段可以控制在I/O事件完成之后,如何通知应用程序。更详细的查阅资料
用aio_read()代码如下:

#include        <signal.h>
#include        <string.h>
#include        <stdlib.h>
#include        <aio.h>
void setup_aio_buffer();
struct aiocb kbcbuf;
main()
{
        setup_aio_buffer();               /* initialize aio ctrl buff */
        aio_read(&kbcbuf);                /* place a read request     */
          while(done){
                if(done == 0)
                        break;
          }
}

void actfun(int signum)
{

        char buf[10];
        read(0,buf,10);
        if(strncmp(kbcbuf.aio_buf,"q",1) == 0)
        {
                done = 0;
                printf("22222222222222 ");
        }
        aio_read(&kbcbuf);                /* place a read request     */
}
void setup_aio_buffer()
{
        static char input[1];                 /* 1 char of input */

        /* describe what to read */
        kbcbuf.aio_fildes     = 0;            /* standard intput */
        kbcbuf.aio_buf        = input;        /* buffer          */
        kbcbuf.aio_nbytes     = 1;             /* number to read  */
        kbcbuf.aio_offset     = 0;             /* offset in file  */

        /* describe what to do when read is ready */
        kbcbuf.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
        kbcbuf.aio_sigevent.sigev_signo  = SIGIO;  /* send sIGIO   */
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值