Как лучше всего использовать сокеты на стороне сервера для обработки многопоточных битых данных в Linux?

Учитывая то, что я новичок в языке C в Linux, я прошел через сценарии программирования сокетов, где вы должны решить эти проблемы SIGPIPE, и я столкнулся с неожиданными случаями:
1 - поймать sigaction для процесса и продолжить, что равняется игнорированию сигнала.

struct sigaction sginal_action;
memset(&sginal_action, 0, sizeof (sginal_action));
sginal_action.sa_handler = SIG_IGN;
sginal_action.sa_flags = SA_RESTART;
if (sigaction(SIGPIPE, &sginal_action, null)) {
    perror("signal action error"); 
}

2 - игнорировать сигнал через поток, используя

sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SA_RESTART, &sigpipe_mask, &saved_mask) == -1) {
  perror("pthread_sigmask");
}



-Теперь все должно работать нормально, но мне нужен ответ о поведении этого теста:

1 - сервер принял сокет от пользователя A с файловым дескриптором int 7
2- Я запускаю длинную инструкцию SQL, которая занимает 25 секунд
3- у второго 20 клиент закрытого сокета
4- во втором ядре Linux 21 отправлено SIGPIPE
5- во втором 22 процесс проигнорировал SIGPIPE и продолжил работу с файловым дескриптором 7, так как нет сигнала, что что-то пошло не так
6- на втором 23 сервере принял сокет от пользователя B с файловым дескриптором int 7, снова!
7- авторизация пользователя B занимает 2 секунды и заканчивается 25 секундами пользователя A.
8 - проблема ядра начинается со второй 25 записи (file_dsciptor, buffer, buffer_size); из обоих потоков будут записывать данные в каналы пользователя A и пользователя B
9- случается, что пользователь B не авторизован для входа в систему на сервере, но до того, как сервер закроет файловый дескриптор 7 в потоке B, поток A клиента A выполняет запись в файловый дескриптор 7, и клиент B получил важные данные из-за повторного использования дескриптора файла сокета 7!

Мой вопрос,
этот сценарий неправильный и никогда не случится?
или это возможно, но есть правильный метод для применения?
и есть ли функция системного вызова C, чтобы остановить повторное использование file_discriptor через соединения с сокетами?
или что нужно сделать, чтобы открытый канал не конфликтовал с другим каналом, как, например, уникальный файловый дескриптор?

1 ответ

(Нормальный) SIGPIPE по сути синхронный сигнал. Вы получаете это в ответ на то, что вы сделали, что попытка записи в канал / сокет /FIFO, который был закрыт другой стороной. игнорирование SIGPIPE является совершенно безвредным, поскольку, если вы сделаете это, вы все равно будете получать информацию об ошибке, как правило, как синхронные ошибки сообщаются: ошибочный код возврата и errno установить соответствующий номер ошибки (EPIPE). В этом случае, я думаю, игнорируя SIGPIPE Продолжая проверять наличие ошибок, вы сможете продолжить работу независимо от используемой вами платформы POSIX.

Что касается вашего примера, ваше предположение в пункте 5 о том, что не будет никакого сигнала, что что-то пошло не так, неверно. Там будет сигнал. Это будет не сигнал, а EPIPE потерпеть неудачу на write вызов.

Другие вопросы по тегам