Linux系统编程 44 阻塞和非阻塞

Linux系统编程 44 阻塞和非阻塞
学习笔记
了解概念
跟他相关的是read和write函数。

如果读的是常规的文件,不会涉及到阻塞和非阻塞。
1.设备文件
2.网络文件

/dev/tty  --- 终端文件

$cat block_readtty.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    char buf[10];
    int n;

    n = read(STDIN_FILENO,buf,10);

    if( -1 == n )
    {
        perror("read STDIN_FILENO\n");
        exit(1);
    }

    write(STDOUT_FILENO,buf,n);
    return 0;
}
$./block_readtty 
song 
song

在UNIX一些系统调用中使用到STDIN_FILENO表示标准输入,STDOUT_FILENO表示标准输出,
STDERR_FILENO表示标准出错,使用时需要加头文件<unistd.h>。


当执行可执行文件的时候,没有输入的时候,就不会有$输出。
STDIN_FILENO值为0 对应标准输入- 键盘
从键盘读到buf中去。

有数据的时候,就会读走,没有数据的时候,就是阻塞。
STDOUT_FILENO 标准输出。

阻塞是谁的特性? 是read/write?
实际上不是,他是文件的属性。只不过常规文件没有这个属性

1.设备文件
2.网络文件
才有这些属性
想改变终端的属性?

O_NONBLOCK.
所以重启打开文件后,加上O_NONBLOCK参数。

read函数的返回值:
成功:读到的字节数
失败:-1,设置为errno
-1:-1 并且errno 为 EAGAIN or EWOULDBLOCK。说明不是文件读取失败,而是read以非阻塞取读取文件,且文件无数据。
EAGAIN 的头文件为 errno.h

$vim noblock_readtty.c
$cat noblock_readtty.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include<string.h>
#include<errno.h>
int main(void)
{
    char buf[10];
    int fd, n;

    fd = open("/dev/tty",O_RDWR|O_NONBLOCK|O_NDELAY);
    if(-1 == fd )
    {
        perror("open /dev/tty error\n");
        exit(1);
    }

tryagain:
    n = read(STDIN_FILENO,buf,10);

    if( n <= 0 )
    {
        printf("errno is %d",errno);
        if((errno !=EAGAIN) ||(errno != EWOULDBLOCK ))
        {
            perror("read /dev/tty error!\n");
            exit(1);
        }
        else
        {
            perror("try again\n");
            write(STDOUT_FILENO,"try again\n",strlen("try again\n"));
            sleep(2);
            goto tryagain;
        }

    }

    write(STDOUT_FILENO,buf,n);
    close(fd);

    return 0;
}

视频中
不输入的时候会提示try again
但是实际上没有,后面要在确认下原因。


实际项目开发不能这样子,不能一直占用终端。修改程序

$cat noblock_readtty_timeout.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include<string.h>
#include<errno.h>
#define MSG_TIMEOUT "TIME OUT!"
int main(void)
{
    char buf[10];
    int i, fd, n;

    fd = open("/dev/tty",O_RDWR|O_NONBLOCK|O_NDELAY);
    if(-1 == fd )
    {
        perror("open /dev/tty error\n");
        exit(1);
    }

    for(i=0;i<5;i++)
    {
        n = read(STDIN_FILENO,buf,10);

        if( n <= 0 )
        {
            printf("errno is %d",errno);
            if((errno !=EAGAIN) ||(errno != EWOULDBLOCK ))
            {
                perror("read /dev/tty error!\n");
                exit(1);
            }
            else
            {
                perror("try again\n");
                write(STDOUT_FILENO,"try again\n",strlen("try again\n"));
                sleep(2);
            }

        }
        else
        {
            break;
        }
    }

    if(5 == i)
    {
        write(STDOUT_FILENO,MSG_TIMEOUT,strlen(MSG_TIMEOUT));

    }
    else
    {

        write(STDOUT_FILENO,buf,n);
    }
    close(fd);

    return 0;
}

视频的效果会输出5次try again 后显式timeout
实际上不是,原因未知!!!
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值