Pause () `Suspected blocking, causing the cycle to fail to terminate.

  c++, question
// bounce_async.c
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h> // pause()
 #include <fcntl.h> // fcntl()
 #include <signal.h> // signal()
 #include <sys/time.h> // set_ticker()
 #include <stdbool.h>
 #include <string.h>
 #include "curses.h" // initscr(), cbreak(), getch(), move(), addstr(), mvaddch(), refresh(), endwin()
 
 #define MESSAGE "hello"
 #define BLANK "     "
 
 int row = 10;
 int col = 0;
 int dir = 1;
 int delay = 200;
 bool done = false;
 
 extern void set_ticker(int n_msecs);
 extern void on_input(int signum);
 extern void enable_kbd_signal(void);
 extern void on_alarm(int signum);
 
 int main(void) {
 initscr();
 cbreak();
 noecho();
 refresh();
 
 signal(SIGIO, on_input);
 enable_kbd_signal();
 signal(SIGALRM, on_alarm);
 set_ticker(delay);
 
 mvaddstr(row, col, MESSAGE);
 
 while (done == false)
 pause();
 
 endwin();
 return EXIT_SUCCESS;
 }
 
 extern void set_ticker(int n_msecs) {
 long n_secs = n_msecs / 1000L;
 long n_usecs = (n_msecs % 1000L) * 1000L;
 
 struct itimerval new_timeset;
 
 new_timeset.it_value.tv_sec = n_secs;
 new_timeset.it_value.tv_usec = n_usecs;
 
 new_timeset.it_interval.tv_sec = n_secs;
 new_timeset.it_interval.tv_usec = n_usecs;
 
 setitimer(ITIMER_REAL, &new_timeset, NULL);
 }
 
 extern void on_input(int signum) {
 int c = getch();
 
 if (c == 'Q' || c == EOF)
 done = true;
 //exit(EXIT_SUCCESS);
 else if (c == ' ')
 dir = -dir;
 }
 
 extern void enable_kbd_signal(void) {
 fcntl(0, F_SETOWN, getpid());
 int fd_flags = fcntl(0, F_GETFL);
 fcntl(0, F_SETFL, fd_flags | O_ASYNC);
 }
 
 extern void on_alarm(int signum) {
 signal(SIGALRM, on_alarm);
 mvaddstr(row, col, BLANK);
 col += dir;
 mvaddstr(row, col, MESSAGE);
 refresh();
 
 if (dir == -1 && col <= 0)
 dir = 1;
 else if (dir == 1 && col + strlen(MESSAGE) >= COLS)
 dir = -1;
 }

Compileclang bounce_async.c -l cursesAnd execute, found pressQUnable to quit program, suspectpause()There was an unexplained blockage. Why? How to solve it?

First of all, don’t compare boolean variables with boolean values … if you thinkdone == falseIt is acceptable, then why don’t you write it(done == false) == true? Why not write it((done == false) == true) == trueWhat about …

As can be seen from strace, pause(2) was called only once, and it was immediately interrupted by SIGIO. therefore, getch(3) was called, and no output was obtained, so it had to wait until SIGALRM interrupted. After reading the data, I was about to return, and there was another SIGIO signal: -D

Why did SIGIO run out at this time? Because the terminal is at this timeIt can be written! Although it is called standard input, its file descriptor flag is the same as standard output:

>>> cat /proc/20583/fdinfo/1
 pos:    0
 flags:  0104002
 mnt_id: 22
 >>> cat /proc/20583/fdinfo/0
 pos:    0
 flags:  0104002
 mnt_id: 22

You can also try writing something into the standard input:-)

PS: Are there many non-reentrant functions used in signal processing functions?