linux下实现键盘的非阻塞输入

文章讲述了如何在Linux环境下,通过设置非阻塞标志(FIONBIO)来实现程序在忽略其他退出信号的情况下,通过读取q键来实现主线程的退出。利用ioctl函数改变标准输入(STDIN_FILENO)的阻塞状态,使得读取键盘输入变为非阻塞,当读取到q时程序退出。
摘要由CSDN通过智能技术生成

    最近遇到一个需求:linux下的程序在忽略其他退出信号的情况下,按q键退出。
    由于主线程需要监听键盘输入,正常情况读取字符串会阻塞,导致主线程无法正常退出,因此考虑用非阻塞的形式实现。
    在linux下每打开一个终端,系统自动的就打开了三个文件,它们的文件描述符分别为0,1,2,功能分别是“标准输入”、“标准输出”和“标准错误输出”,同时对应了三个文件流指针,分别是stdin,stdout和stderr。

使用ioctl清除非阻塞标志

函数原型:

int ioctl(int d, int request, …);

参数:

d:文件描述符

request:功能码。根据填写的功能码选择第三个参数。

返回:

成功返回0,失败返回-1。

ioctl函数传入的第二个参数为FIONBIO表示“设置/清除非阻塞标志”,那么第三个参数要传入一个int类型的指针,指针指向的值为1表示设置非阻塞标志,那么对应的文件描述符为非阻塞,指针指向的值为0表示清除非阻塞标志,那么对应的文件描述符为阻塞。
  因此调用如下代码即可实现非阻塞:

int attr = 1;
ioctl(STDIN_FILENO, FIONBIO, &attr);   /* 清除非阻塞标志 */

完整代码如下:

// 处理中途退出程序
    char buf[128] = { 0 };
    int len = 0;
    int total = 0;
    int attr = 1;
    ioctl(STDIN_FILENO, FIONBIO, &attr);   /* 清除非阻塞标志 */
    printf("input 'q' to quit \n");
    while (!read_quit || !send_quit)
    {
        len = read(STDIN_FILENO, &buf[total], sizeof(buf) - total);
        //printf("len = %d\n", len);
        if (len > 0) {
            total += len;
            if (buf[total - 1] == '\n') {
                //printf("total = %d\n", total);
                //printf("buf = %s\n", buf);
                if (buf[0] == 'q') 
                {
                    //退出处理
                    break;
                }
                total = 0;
                memset(buf, 0, sizeof(buf));
            }
        }
        msleep(2000);
    }
    //退出时记得恢复阻塞输入
    attr = 0;
    ioctl(STDIN_FILENO,FIONBIO,&attr);//attr为0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值