阻塞IO与非阻塞IO


阻塞IO与非阻塞IO

阻塞IO

    默认情况下,Linux系统上的所有文件描述符都以阻塞模式开始。 这意味着I / O系统调用如读取,写入或连接可能会阻塞。

   如果你在stdin上调用read,那么你的程序将被阻塞,直到数据实际可用,例如当用户实际上在他们的键盘上物理键入字符时。具体来说,内核会将进程置于“睡眠”状态,直到数据在stdin上可用。

   网络传输中,如果你尝试从TCP套接字读取,则读取调用将阻塞,直到连接的另一端实际发送数据。这种网络设置在高并发环境下就是灾难,因为只要达到阻塞的上限,那么剩下请求则没法处理。

非阻塞IO

    非阻塞IO在没有数据处理的情况下直接返回且errno = 11。errno 在errno.h的定义如下:

    #define EAGAIN      11  /* Try again */


设置非阻塞IO的方式

1使用fcntl在文件描述符上设置O_NONBLOCK

        /*STDIN_FILENO 开启非阻塞模式 */

        int flags = fcntl(STDIN_FILENO,F_GETFL,0);

        fcntl(STDIN_FILENO,F_SETFL,flags | O_NONBLOCK );

        /*STDIN_FILENO 开启非阻塞模式 */


        /* STDIN_FILENO 关闭非阻塞模式*/

        flags = fcntl(STDIN_FILENO,F_GETFL,0);

        fcntl(STDIN_FILENO,F_SETFL,flags & (~O_NONBLOCK) );


2使用open函数,其中flags项包括O_NONBLOCK。

        /*open函数设置描述符,开启非阻塞模式 */

        int fd =open("test",O_RDWR|O_CREAT|O_NONBLOCK);


测试代码

#include <errno.h>

#include <fcntl.h>

#include <stdlib.h>

#include <stdio.h>

#include<sys/types.h>

#include<sys/stat.h>

#include <unistd.h>





char    buf[500000];



int

main(void)

{

        int             ntowrite, nwrite;

        char    *ptr;

        

        /*STDIN_FILENO 开启非阻塞模式 */

        int flags = fcntl(STDIN_FILENO,F_GETFL,0);

        fcntl(STDIN_FILENO,F_SETFL,flags | O_NONBLOCK );

        /*STDIN_FILENO 开启非阻塞模式 */



        /*从STDIN_FILENO读取数据,如果是非阻塞模式,没读到数据则立刻返回        */

        ntowrite = read(STDIN_FILENO, buf, sizeof(buf));

        fprintf(stderr, "read %d bytes\n", ntowrite);

        

        /*open函数设置描述符,开启非阻塞模式 */

        int fd =open("test",O_RDWR|O_CREAT|O_NONBLOCK);



        ptr = buf;

        while (ntowrite > 0) {

                errno = 0;

                nwrite = write(fd, ptr, ntowrite);

                fprintf(stderr, "nwrite = %d, errno = %d\n", nwrite, errno);



                if (nwrite > 0) {

                        ptr += nwrite;

                        ntowrite -= nwrite;

                }

        }



        /* STDIN_FILENO 关闭非阻塞模式*/

        flags = fcntl(STDIN_FILENO,F_GETFL,0);

        fcntl(STDIN_FILENO,F_SETFL,flags & (~O_NONBLOCK) );

        close(fd);

        exit(0);

}



参考链接

[1]. https://www.mkssoftware.com/docs/man5/stdio.5.asp 

[2]. http://www.virtsync.com/c-error-codes-include-errno


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值