Váš úkol vyžaduje smyčku událostí založenou na select
nebo epoll
. Jedna událost, na kterou by čekal, je vstup uživatele - když STDIN_FILENO
bude připraven ke čtení. Dalším je 1sekundový periodický časovač, když potřebujete dotazovat ovladač.
Existuje poměrně málo knihoven, které za vás implementují smyčku událostí, abyste se mohli soustředit na to, jaké události potřebujete zpracovat a jak. libevent
je jedním z nejstarších, bohatých na funkce a populární.
Domnívám se, že „unixovým“ způsobem by nebylo žádat o vstup uživatele, ale reagovat na signál uživatele. Například, když uživatel stiskne Ctrl-C, aktuálně běžící proces obdrží SIGINT.
Příklad, jak správně použít SIGINT k přerušení smyčky, naleznete zde. Zkopírujte jej do odpovědi pro případ, že by odkaz zastaral:
#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;
}
(ve vašem případě by bylo dobré zadat break;
do if
blokovat nebo použít while(!got_signal)
)
Jednoduchá odpověď je multi-threading, kde máte vlákno nasazené, aby čekalo na vstup uživatele, zatímco smyčka pokračuje. Takže tohle:
char flag = 1;
while (flag) {
// run the loop
// if thing happens deploy the thread which will ask user for input
}
Chvíli jsem nedělal vlákna, myslím, že tato stránka by byla lepší, než abych se vám to snažil vysvětlit:https://randu.org/tutorials/threads/