gpt4 book ai didi

取消 getchar()

转载 作者:太空宇宙 更新时间:2023-11-03 23:54:23 27 4
gpt4 key购买 nike

我有一个执行大量处理的小程序。您可以通过按回车键打印进度。

我实现它的方法是在主线程中完成处理,同时我有一个 pthread 不断循环 getchar() 以等待输入键。

问题是当我完成处理时。发生这种情况时,主线程结束,但仍等待按下 enter,因为 getchar() 正在阻塞。

如何“取消”getchar()?

最佳答案

我能想到的最便携的解决方案是:

  • 使用pipe() 构造两个FD,一个是reader,另一个是writer。让读者进入你的 read() 循环;将作者交给需要终止读者的任何人。
  • 使用读取线程中的 select() 来等待标准输入和读取器管道的可读性。
  • 如果标准输入变得可读,读取一个字符,处理它,然后重新开始循环。
  • 如果读取器管道变得可读,则关闭它并终止循环。

现在,您所要做的就是关闭管道的另一端,这会将读取器线程从其 select() 中唤醒,然后它应该终止。

传统方法涉及使用信号,但是这种基于管道的解决方案允许您检查 stdin 上的输入以及检查是否应该使用相同的轮询机制终止。


请注意,混合使用 getchar()select() 将不起作用,因为 getchar() 将有效地使用 fread( ) 在引擎盖下,并且由 fread() 执行的缓冲会导致 select() 阻塞,即使有数据可用也是如此。请改用 read()。这是我用来测试这种方法的示例程序。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/select.h>

void * entry_point(void * p) {
int readpipe = *(int *)p;
fd_set rfds;

char c;

for (;;) {
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
FD_SET(readpipe, &rfds);

while (select(readpipe + 1, &rfds, NULL, NULL, NULL) == 0);

if (FD_ISSET(readpipe, &rfds)) {
close(readpipe);
break;
}

if (FD_ISSET(STDIN_FILENO, &rfds)) {
if (read(STDIN_FILENO, &c, sizeof(c)) > 0) {
printf("Read: %d\n", c);
}
}
}

printf("Thread terminating\n");

pthread_exit(NULL);
}

int main() {
pthread_t thread;
int r;
int pipes[2];

pipe(pipes);

if (r = pthread_create(&thread, NULL, entry_point, &pipes[0])) {
printf("Error: %d\n", r);
return 1;
}

sleep(5);

printf("Closing pipe and joining thread.\n");

close(pipes[1]);
pthread_join(thread, NULL);

pthread_exit(NULL);
}

运行示例:

$ time ./test
1
Read: 49
Read: 10
2
Read: 50
Read: 10
3
Read: 51
Read: 10
4
Read: 52
Read: 10
5
Read: 53
Read: 10
Closing pipe and joining thread.
Thread terminating

real 0m5.004s
user 0m0.004s
sys 0m0.000s

关于取消 getchar(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11513593/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com