Эффективное программирование TCP-IP




Использование вызова alarm - часть 2


Еще одна потенциальная проблема в том, что некоторые UNIX-системы могут автоматически возобновлять вызов connect после возврата из обработчика сигнала. В таком случае connect не вернет управления, пока не истечет тайм-аут TCP. Во всех современных вариантах системы UNIX поддерживается вызов sigaction, который можно использовать вместо signal. В таком случае следует указать, хотите ли вы рестартовать connect. Но в некоторых устаревших версиях UNIX этот вызов не поддерживается, и тогда использование alarm для прерыва ния connect по тайм-ауту затруднительно.

Если нужно вывести всего лишь диагностическое сообщение и завершить сеанс, то это можно сделать в обработчике сигнала. Поскольку это происходит до рес тарта connect, не имеет значения, поддерживает система вызов sigaction или не. Однако если нужно предпринять какие-то другие действия, то, вероятно, придется выйти из обработчика с помощью функции longjmp, а это неизбежно приводит к возникновению гонки.

Примечание: Следует заметить, что гонка возникает и в более простом случае, когда вы завершаете программу. Предположим, что соединение успешно установлено, и connect вернул управление. Однако прежде чем вы успели его отменить, таймер сработал, что привело к вызову обработчика сигнала и, следовательно, к завершению программы.

alarm( 5 };

rc = connect( s, NULL, NULL );

/* здесь срабатывает таймер */

alarm ( 0 );

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

Принимая это во внимание, многие эксперты считают, что для прерывания вызова connect по тайм-ауту лучше использовать select.




Содержание  Назад  Вперед