【问题标题】:Using threads in C to create an asynchronous timer使用 C 中的线程创建异步计时器
【发布时间】:2021-08-05 15:30:05
【问题描述】:

我什至不确定线程​​是否是我想要完成的工作的一种方式,但我的直觉告诉我。

我在 while 循环中逐个字符地实现一个简单的输入。如果字符输入之间的时间大于 2 秒,则应该发生超时。超时目前是main函数中的一个简单的printf。

这是我的代码:

typedef struct {
    clock_t startTime;
} timerStruct;

void *TimerThread(void *arg) {
    timerStruct timerThreadArgument = *((timerStruct *) arg);
    clock_t differenceTime;
    while(1) {
        differenceTime = clock() - timerThreadArgument.startTime;
        int millis = differenceTime * 1000 / CLOCKS_PER_SEC;
        
        if (millis >= TIMEOUT_TIME) {
            return (void *) 2;
        }
    }
}

int main() {
    pthread_t timerThreadId;
    void *threadReturn;
    char inputChar;
    
    printf("Input characters one by one or paste the string:\n");
    
    while (1) {
        timerStruct *timerThreadArgument = malloc(sizeof(*timerThreadArgument));
        timerThreadArgument->startTime = clock();
        
        pthread_create(&timerThreadId, NULL, TimerThread, timerThreadArgument);
        pthread_join(timerThreadId, &threadReturn);
        
        if ((int) threadReturn == 2) {
            printf("Timeout!\n");
        }
        
        scanf(" %c", &inputChar);
        
    }
}

问题是,由于我使用的是 pthread_join 函数,它会阻止主线程执行和请求输入。我知道为什么会这样。如果我不使用 pthread_join 函数,我将无法从线程返回数据,这很重要,因为如果发生超时,我希望打破 while 循环。

如果有人对我如何解决这个问题有任何想法,请分享。 提前感谢您的宝贵时间。

【问题讨论】:

  • 线程对此没有帮助。线程的合理使用只与计算绑定程序有关,而不是 I/O,尤其是不是 I/O 超时。
  • 您应该在标准输入上使用 poll() 并设置超时时间。

标签: c multithreading timer pthreads


【解决方案1】:

您正在尝试的内容存在许多问题。其中之一是stdio(即scanf)涉及缓冲;所以在整行可用之前,您不会得到单个字符。另一个是你实现的更像是 sleep() 而不是超时。

为了直接控制 tty 输入,您需要通知内核中的设备驱动程序您的愿望。对此的标准接口是 tcgetattr、tcsetattr;这可以对 tty 进行相当细粒度的控制。 n?curses 库稍微粗糙一些,但使用起来要容易得多。

将系统设计为一组相互提供事件的异步服务有很多优点。在这种情况下,您的键盘处理可能会占用一个线程,将“键事件”发送到某种调度程序;也许还有另一个发送“警报事件”来跟踪超时。不过,这不是一个特别简单的模式。它的价值只在相对较大的系统中脱颖而出。

一些较新的编程语言,例如 Go,具有专门针对这种架构的结构。您可能会发现值得一看,至少可以了解它是如何完成的。

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 2021-11-22
    • 2013-03-30
    • 2018-01-12
    • 1970-01-01
    相关资源
    最近更新 更多