Какова лучшая практика сокетов на стороне сервера для обработки многопоточных битых данных в Linux? - PullRequest
0 голосов
/ 18 мая 2018

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

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 72- Я запускаю длинную инструкцию SQL, которая занимает 25 секунд3- во втором 20 закрытом сокете клиента4- на секунду 21 ядро ​​Linux отправило SIGPIPE5- во втором 22 процесс игнорировал SIGPIPE и продолжал работать с файловым дескриптором 7, так как нет сигнала, что что-то пошло не так6- на втором 23 сервере принял сокет от пользователя B с файловым дескриптором int 7, снова!7- авторизация пользователя B занимает 2 секунды и заканчивается 25 секундами пользователя A.8- проблема с ядром начинается при второй 25 записи (file_dsciptor, buffer, buffer_size);из обоих потоков будут записывать данные в каналы пользователя A и пользователя B9 - случается, что пользователь B не авторизован для входа на сервер, но до того, как сервер закроет файловый дескриптор 7 в потоке B, поток A клиента A выполняет запись в файловый дескриптор 7, и клиент B получил важные данные из-за повторного использования дескриптора файла сокета 7!Мой вопрос,этот сценарий неправильный и никогда не случится?или это возможно, но есть правильный метод для применения?и есть ли функция системного вызова C, чтобы остановить повторное использование file_discriptor через соединения с сокетами?или что нужно сделать, чтобы открытый канал не конфликтовал с другим каналом, как, например, уникальный файловый дескриптор?

1 Ответ

0 голосов
/ 18 мая 2018

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

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

...