タスクには select
に基づくイベント ループが必要です または epoll
.待機するイベントの 1 つはユーザー入力です - STDIN_FILENO
の場合 読み取り可能になります。もう 1 つは、コントローラーをポーリングする必要がある場合の 1 秒周期のタイマーです。
どのイベントをどのように処理する必要があるかに集中できるように、イベント ループを実装するライブラリが多数あります。 libevent
最も古く、機能が豊富で人気のあるものの 1 つです。
「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/