【问题标题】:C non-blocking keyboard input blocks on run level 3 (Linux)运行级别 3 (Linux) 上的 C 非阻塞键盘输入块
【发布时间】:2020-03-29 04:14:10
【问题描述】:

我有一段代码读取键盘输入(用于调试目的),在 Ubuntu 18.04 上用 C 语言实现。由于其他进程必须在同一个线程上运行,所以它被初始化为非阻塞。

当我尝试在运行级别 3 上运行我的应用程序时,它会在尝试读取键盘字符时阻塞。当我在运行级别 5 上运行应用程序时,不会发生此行为。

对于为什么这两个运行级别之间的行为不一致,有人有任何答案吗?

这是代码(未显示:读取操作由应用程序的主循环调用):

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>


static int fd;

int kbd_initModule()
{
    fd = open("/dev/tty", O_NONBLOCK | O_NOCTTY);

    if(fd < 0)
    {
        ERROR("Unable to open keyboard: %d", fd);
        return fd;
    }
    else
    {
        return 0;
    }
}

int kbd_deinitModule()
{
    close(fd);
    return 0;
}

int kbd_getEvent()
{
    uint8_t buf[1];

    int tmp = read(fd, buf, sizeof(buf));

    if(tmp == -1)
    {
        ERROR("%s", strerror(errno));
        return -1;
    }
    else
    {
        return buf[0];
    }
}

我可以回答任何问题并提供更多详细信息。

其他详情:

  • 启动应用程序:运行级别 5:sudo ./app;运行级别 3:sudo xinit ./app(应用中有 GUI 组件,因此 X 服务器必须在运行级别 3 上启动 - 如果有人对此了解更多,那就太好了)。

【问题讨论】:

  • 程序运行得怎么样?
  • 运行级别 5:sudo ./app ;运行级别 3:sudo xinit ./app
  • 所以这是问题中需要解决的一件事:您正在使用不同的命令来运行应用程序。另外,您如何知道它是否阻止或不阻止?阻止?
  • xinit 手动启动 X 显示服务器(因为我们在运行级别 3 下以 CLI 模式运行)。你知道这是否会干扰 I/O 吗?大概xinit 在运行级别 5 下启动时会自动调用...我们知道该函数在运行级别 5 下不会阻塞,因为其他应用程序进程正在正确运行,而在运行级别 3 下并非如此。跨度>
  • 所以您看到其他进程没有运行,因此您假设从 /dev/tty 读取必须是阻塞的?

标签: c linux io ubuntu-18.04 tty


【解决方案1】:

更新: 如果您在运行级别 3 上初始化当前 tty 设备,它就不起作用。初始化到特定的 tty 设备(在本例中为 tty3)可以解决问题。

不太确定为什么会这样(也许运行级别 3 上的默认 tty 是 X 窗口?),如果有人能解释为什么会发生这种情况,将不胜感激。

【讨论】:

    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 2016-07-04
    • 1970-01-01
    • 2012-03-14
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多