прервана ошибка системного вызова при записи в канал - PullRequest
2 голосов
/ 06 мая 2011

В моем пользовательском приложении Linux у меня есть нить, которая общается с основным процессом через канал. Ниже приведен код

static void _notify_main(int cond)
{
    int r;
    int tmp = cond;

    r = write( _nfy_fd, &tmp, sizeof(tmp) );
    ERROR( "write failed: %d. %s\n",  r, strerror(r) );
}

Довольно прямо. Это работает нормально в течение достаточно долгого времени. Но в последнее время вызов write завершится с ошибкой «прерванный системный вызов» после того, как программа прошла стресс-тест.

Странно, но материал на самом деле прошел через трубу без проблем. Конечно, я все же хотел бы перейти к нижней части сообщения об ошибке и избавиться от него.

Спасибо

Ответы [ 2 ]

2 голосов
/ 06 мая 2011

Страница man write (2) упоминает:

Соответствует SVr4, 4.3BSD, POSIX.1-2001.

Под SVr4 a writeможет прерваться и вернуть EINTR в любой момент, а не только до того, как будут записаны какие-либо данные.

Полагаю, вам просто повезло, что этого не произошло до сих пор.

Если вы загляните в Google только ради "прерванного системного вызова", вы найдете эту тему, который говорит вам использовать siginterrupt() для автоматического перезапуска вызова write.

0 голосов
/ 11 февраля 2014

С http://www.gnu.org/

Сигнал может поступать и обрабатываться, пока примитив ввода-вывода, такой как открытие или чтение, ожидает устройства ввода-вывода.Если обработчик сигнала возвращается, система сталкивается с вопросом: что должно произойти дальше?

POSIX определяет один подход: заставить примитив сразу выйти из строя.Код ошибки для этого типа ошибки EINTR.Это гибкий, но обычно неудобный.Как правило, приложения POSIX, использующие обработчики сигналов, должны проверять EINTR после каждой библиотечной функции, которая может его вернуть, чтобы повторить вызов.Часто программисты забывают проверить, что является распространенным источником ошибок.

Таким образом, вы можете обработать ошибку EINTR, есть другой выбор, кстати, вы можете использовать sigaction, чтобы установить обработчик сигнала, определяющий, какэтот обработчик должен вести себяИспользуя флаг SA_RESTART, возврат из этого обработчика возобновит примитив;в противном случае возврат из этого обработчика вызовет EINTR.

см. прерванные примитивы

...