繁体   English   中英

C程序如何在Linux环境中同时执行其他操作的同时轮询用户输入?

[英]How can a C program poll for user input while simultaneously performing other actions in a Linux environment?

背景:

我是一个相对缺乏经验的开发人员,他试图编写软件来与PCI运动控制器连接。 我在Ubuntu Linux 18.04上使用C(用gcc编译)。

我正在编写的程序需要定期检查运动控制器发送的未经请求的状态消息(大约每秒一次)并显示它在终端屏幕上找到的任何消息(我正在使用ncurses库)。

是)我有的:

现在,要做到这一点,我正在调用一个函数来检查while循环中的未经请求的消息。 代码大致类似于:

while (1)
{
    // check for messages from PCI and store them in a traffic buffer
    checkForMessages(PCIconnection, trafficBuffer);

    // output the traffic buffer to the screen
    printf("%s", trafficBuffer);    
}

我需要的:

我需要以允许它们结束循环的方式提示用户输入。 例如,用户可以输入end使循环停止并且程序继续。

问题:

我不知道如何在不将fgets放入while循环的情况下实现此目的,导致程序停止并等待用户在每次循环迭代中输入内容。

我已经找到了解决方案,但是我还没有找到关于如何实现我需要的功能的讨论。 打开一个新的线程或过程似乎是朝着正确方向迈出的一步?

如果我目前正在做的是糟糕的做法,我愿意完全重构我的代码。

感谢您的任何帮助!

您的任务需要基于selectepoll事件循环 它等待的一个事件是用户输入 - 当STDIN_FILENO准备好读取时。 另一种是需要轮询控制器时的1秒周期定时器。

有很多库为您实现了一个事件循环,因此您可以专注于您需要处理的事件以及如何处理。 libevent是最古老,功能丰富且最受欢迎的之一。

我相信“Unix”的方式不是要求用户输入,而是要对用户信号做出反应。 例如,当用户按下Ctrl-C时,当前正在运行的进程接收SIGINT。

可以在此处找到如何正确使用SIGINT来中断循环的示例。 将链接变为陈旧时将其复制到答案中:

#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

static volatile sig_atomic_t got_signal = 0;

static void my_sig_handler(int signo)
{
    got_signal = 1;
}

int main()
{
    struct sigaction sa;

    memset(&sa, 0, sizeof(struct sigaction));
    sa.sa_handler = &my_sig_handler;
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction");
        return EXIT_FAILURE;
    }

    for (;;) {
        if (got_signal) {
            got_signal = 0;
            printf("Received interrupt signal!\n");
        }
        printf("Doing useful stuff...\n");
        sleep(1); /* Sleep is not only useful, it is essential! */
    }
    return EXIT_SUCCESS;
}

(在你的情况下,将break;放入if块或使用while(!got_signal) )是个好主意

简单的答案是多线程,您可以在其中部署线程以等待用户输入,同时循环继续。 所以有这个:

char flag = 1;

while (flag) {
     // run the loop

     // if thing happens deploy the thread which will ask user for input

}

我有一段时间没有做过线程,我认为这个页面会比我试图向你解释更好: https//randu.org/tutorials/threads/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM