В настройках BIOS (нажмите F2 после включения компьютера) установите загрузку с UEFI вместо устаревшей
Прерывание системного вызова обработчиком сигнала происходит только в случае различных блокирующих системных вызовов и происходит, когда системный вызов прерывается обработчиком сигнала, явно установленным программистом.
Кроме того, в случае, когда блокирующий системный вызов прерывается обработчиком сигнала, автоматический перезапуск системного вызова является дополнительной функцией. Вы выбираете автоматический перезапуск системных вызовов, указав флаг SA_RESTART
при установке обработчика сигнала. Как указано в (, например )Linux signal (7)страница руководства:
If a signal handler is invoked while a system call or library
function call is blocked, then either:
* the call is automatically restarted after the signal handler
returns; or
* the call fails with the error EINTR.
Which of these two behaviors occurs depends on the interface and
whether or not the signal handler was established using the
SA_RESTART flag (see sigaction(2)).
Как намекает последнее предложение, процитированное выше, даже если вы решите использовать эту функцию, она не работает для всех системных вызовов, а набор системных вызовов, для которых она работает, зависит от реализации UNIX. На странице руководства Linux signal(7)
указано несколько системных вызовов, которые автоматически перезапускаются при использовании флага SA_RESTART
.но также отмечает различные системные вызовы, которые никогда не перезапускаются, даже если вы укажете этот флаг при установке обработчика, включая:
* "Input" socket interfaces, when a timeout (SO_RCVTIMEO) has been
set on the socket using setsockopt(2): accept(2), recv(2),
recvfrom(2), recvmmsg(2) (also with a non-NULL timeout argu‐
ment), and recvmsg(2).
* "Output" socket interfaces, when a timeout (SO_RCVTIMEO) has
been set on the socket using setsockopt(2): connect(2), send(2),
sendto(2), and sendmsg(2).
* File descriptor multiplexing interfaces: epoll_wait(2),
epoll_pwait(2), poll(2), ppoll(2), select(2), and pselect(2).
* System V IPC interfaces: msgrcv(2), msgsnd(2), semop(2), and
semtimedop(2).
Для этих системных вызовов необходим ручной перезапуск с использованием цикла, описанного в APUE, что-то вроде:
while ((ret = some_syscall(...)) == -1 && errno == EINTR)
continue;
if (ret == -1)
/* Handle error */ ;
[Я не читал про APUE, но то, что вы цитируете, выглядит не очень]
if my program uses a system call, it would be interrupted/stopped, if at any time the program catches a signal.
Не любой системный вызов. Только некоторые системные вызовы могут быть прерваны.
(Does default handler also count as a catch?)
№
For example, if I have a read system call, which reads 10GB data, when it's reading, I send any one of signals(e.g.kill -SIGUSR1 pid), then read would fail and return.
Прочитанные вами 10 ГБ ()вернутся с EINTR только в том случае, если они были прерваны до того, как вы смогли прочитать хотя бы один байт ; в противном случае он вернет объем данных, который уже был прочитан (short read = success, errno не имеет значения ).
[это не было объяснено в связанном обмане]
So if I my understanding are all correct, what/why should I care about interrupted system call now..? It seems the system/OS handles it automatically.
Потому что вы можете захотеть что-то сделать после получения сигнала, а обработчик сигнала мало что может сделать; ни о чем, использующем malloc ()или stdio (, даже о printf ())не может быть и речи. Таким образом, вы должны обрабатывать прерывания в основном цикле программы, и чтобы иметь возможность сделать это, вы должны как-то выйти из блокирующего чтения ()(, чтение ()может блокироваться даже после возврата опроса (). fd как готовый к чтению ).
[это было также объяснено в связанном обмане]