此任务通常使用线程完成。在一个线程getchar
被调用阻止线程执行时,另一个线程执行sleep()
然后杀死第一个线程。
read()
另一种方法是使用标准输入使用非阻塞pselect (2)
,但它更棘手并且不适合小型应用程序。
尽管 unix 风格的解决方案pthreads
非常冗长:
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
struct read_int {
int success;
int value;
struct timespec timeout;
};
void* read_thread(void *arg) {
struct read_int *s = arg;
printf("Enter a number: ");
scanf("%d", &s->value);
s->success = 1;
return NULL;
}
#define CHECK_RET(ret, func) \
if (ret) { fprintf(stderr, func"() == %d\n", ret); return ret; }
int main() {
pthread_t rthr;
pthread_attr_t thr_attr;
struct read_int s = { 0 };
int ret;
ret = clock_gettime(CLOCK_REALTIME, &s.timeout);
if (ret == -1) { fprintf(stderr, "clock_gettime() == %d\n", ret); return ret; }
s.timeout.tv_sec += 5;
ret = pthread_attr_init(&thr_attr);
CHECK_RET(ret, "pthread_attr_init");
ret = pthread_create(&rthr, &thr_attr, read_thread, &s);
CHECK_RET(ret, "pthread_create");
ret = pthread_attr_destroy(&thr_attr);
CHECK_RET(ret, "pthread_attr_destroy");
pthread_timedjoin_np(rthr, NULL, &s.timeout);
if (s.success) {
printf("\ngot value %d\n", s.value);
} else {
pthread_cancel(rthr);
printf("\nTimed out, exiting...\n\n");
}
}