(Также, чтобы ответить на повторяющийся / закрытый вопрос Как я могу приостановить или заморозить запущенный процесс? , спрашивая, что делать в случае сбоя приложений после возобновления работы.)
Есть процессы, которые не возобновляются. правильно после kill -STOP $ PID
и kill -CONT $ PID
. В этом случае вы можете попробовать контрольную точку / восстановление с CRIU . Если вы не возражаете против накладных расходов, вы также можете запустить процесс на виртуальной машине, которую вы можете приостановить.
Одна из причин, по которой процесс не возобновляется после SIGSTOP / SIGCONT, может заключаться в том, что некоторые системные вызовы блокировки в Linux завершаются ошибкой с EINTR, когда процесс останавливается, а затем возобновляется через SIGCONT. Из signal (7) :
Прерывание системных вызовов и функций библиотеки стоп-сигналами
В Linux, даже при отсутствии обработчиков сигналов, некоторые интерфейсы блокировки могут выйти из строя с ошибка EINTR после того, как процесс остановлен одним из сигналов остановки, а затем возобновлен через SIGCONT. Такое поведение не санкционировано POSIX.1 и не встречается в других системах.
[...]
Один из затронутых системных вызовов - epoll_wait (2) . Пример:
#include
#include
#include
#include
int
main(int argc, char *argv[])
{
int fd = 0;
int efd = epoll_create(1);
if (efd == -1) {
perror("epoll_create");
exit(1);
}
struct epoll_event ev;
memset(&ev, 0, sizeof(ev));
ev.events = EPOLLIN;
ev.data.fd = fd;
if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev) == -1) {
perror("epoll_ctl");
exit(1);
}
int res = epoll_wait(efd, &ev, 1, -1);
if (res == -1) {
perror("epoll_wait");
exit(1);
}
if (ev.events & EPOLLIN && ev.data.fd == fd) {
printf("Received input\n");
}
return 0;
}
Скомпилируйте и запустите:
$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+ Stopped ./example
$ fg
./example
epoll_wait: Interrupted system call
Теперь мне удалось определить проблему самостоятельно. :Я выбрал неправильный тип таблицы разделов. Если вы хотите установить ОС, всегда разделяйте ее как MBR (, называемую «msdos» в GParted ). Теперь все работает нормально, и я могу запустить все, даже если выберу тот же диск в UEFI.