c - pthread 回调中断用户输入

标签 c posix pthreads callback

我已经编写了自己的秒表模块。这将创建一个线程并休眠几秒钟。一旦秒数到期,它将调用 main.c 中的回调函数并通知用户时间已到期。

这样一来,用户只有 3 秒的时间输入一个数字,他们必须输入 5 个数字。如果时间到期,程序必须停止。

2个问题。 1) 如果他们在要求的时间内输入数字。我怎样才能取消线程。我在考虑使用 thread_kill 或 thread_cancel? 2) 如何在 do_while 循环中终止?因为 scanf 会在等待用户输入时阻塞。

非常感谢您的任何建议,

我的代码如下:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#include "stop_watch.h"

struct data_struct *g_data_struct;

void timeout_cb(int id)
{
    printf("Digit timeout\n");
    free(g_data_struct);
}

int main()
{
    pthread_t thread_id;
    unsigned int digit = 0;

    g_data_struct = (struct data_struct*) calloc(1, sizeof(*g_data_struct));

    if(!g_data_struct)
    {
        printf("=== failed to allocate memory ===\n");
        return 0;
    }

    /* start timer for 3 seconds */
    g_data_struct->seconds = 3;
    g_data_struct->func_ptr = timeout_cb;
    thread_id = start_stopwatch(g_data_struct);

    do
    {
        printf("Enter digit: ");
        scanf("%d", &digit);
    }while(1);

    pthread_join(thread_id, NULL);
    printf("=== End of Program - all threads in ===\n");

    free(g_data_struct);

    return 0;
}



#include <stdio.h>
#include <pthread.h>

#include "stop_watch.h"

pthread_t thread_id;
static id = 10;

/* start sleeping and call the callback when seconds have expired */
static void* g_start_timer(void *args)
{
    void (*function_pointer)(int id);
    int seconds = ((struct data_struct*) args)->seconds;
    function_pointer = ((struct data_struct*) args)->func_ptr;

    sleep(seconds);

    (void) (*function_pointer)(id);

    pthread_exit(NULL);

    return 0;
}

/* Will sleep in its own thread for a period of seconds */
int start_stopwatch(struct data_struct *g_data_struct)
{
    int rc = 0;

    int seconds = g_data_struct->seconds;
    printf("=== start_stopwatch(): %d\n", seconds);

    rc =  pthread_create(&thread_id, NULL, g_start_timer, (void *) g_data_struct);

    if(rc)
    {    
        printf("=== Failed to create thread\n");
        return 1;
    }

    return thread_id;
}

顺便说一下,这个问题是关于 C99 gcc 的。

最佳答案

首先,我不建议为此使用单独的线程。但由于它看起来像是学习如何使用线程的练习,所以我将继续学习。

您可以设置一个全局 bool 标志,指示是否输入了数字。在 g_start_timer 中,就在调用 function_pointer 之前,检查标志是否已设置。如果是,请不要调用该函数。

如果你想让线程早点死掉,在它的休眠期结束之前,你可以使用带有 try 锁的互斥锁。

编辑:既然你说这不是练习,我会提到我会怎么做。要么使用在等待标准输入时可能超时的函数,例如 select() 或 poll()。或者,使用 alarm() 来中断。下面是一个使用闹钟的例子:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>

void alarm_signal(int signum)
{
}

int main()
{
    char c;
    unsigned int v = 0;
    struct sigaction act;
    puts("Enter digit: ");

    /* Register dummy handler for alarm */
    act.sa_handler = &alarm_signal;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaction(SIGALRM, &act, NULL);

    /* Set timer for 3 seconds */
    alarm(3);

    /* Read the digits */
    errno = 0;
    while(0 != read(STDIN_FILENO, &c, 1))
    {
        if(c < '0' || c > '9')
            break;
        v = v*10 + c - '0';
    }
    if(errno == EINTR)
        puts("Timed out");
    else
        printf("Value is %d\n", v);
    return 0;
}

关于c - pthread 回调中断用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/611672/

相关文章:

C - 使用带 ** 参数的函数释放结构的已分配内存

c - 将 sig_atomic_t 标志与阻塞调用一起使用

c - aio_write() 的简单示例

c - C 中的同步对象及其与数据结构结构的关联

c++ - 如何处理析构函数中销毁互斥体失败的情况

c - 使用 C 无法读取 4 字节整数 (Int32) 文件

c - 将大数放入数组中

python - 在多线程 C 应用程序中嵌入 python

timezone - 什么是正确的 POSIX 风格 TZ 格式 : <+04>-4 vs UNK-4

c - 如何用 clone() 替换 pthread_join() 和 pthread_create()