Подтвердить что ты не робот

SIGPIPE, Сломанная труба

Я работаю над сетевой программой, использующей epoll на Linux-машине, и я получил сообщение об ошибке из gdb.

Program received signal SIGPIPE, Broken pipe.
[Switching to Thread 0x7ffff609a700 (LWP 19788)]
0x00007ffff7bcdb2d in write () from /lib/libpthread.so.0
(gdb)
(gdb) backtrace
#0  0x00007ffff7bcdb2d in write () from /lib/libpthread.so.0
#1  0x0000000000416bc8 in WorkHandler::workLoop() ()
#2  0x0000000000416920 in WorkHandler::runWorkThread(void*) ()
#3  0x00007ffff7bc6971 in start_thread () from /lib/libpthread.so.0
#4  0x00007ffff718392d in clone () from /lib/libc.so.6
#5  0x0000000000000000 in ?? ()

Мой сервер делает n ^ 2 расчет времени, и я попытался запустить сервер с 500 подключенными пользователями. Что может вызвать эту ошибку? и как это исправить?


       while(1){
            if(remainLength >= MAX_LENGTH)
                currentSentLength = write(client->getFd(), sBuffer, MAX_LENGTH);
            else
                currentSentLength = write(client->getFd(), sBuffer, remainLength);


            if(currentSentLength == -1){
                log("WorkHandler::workLoop, connection has been lost \n");
                break;
            }
            sBuffer += currentSentLength;
            remainLength -= currentSentLength;

            if(remainLength == 0)
                break;
        }
4b9b3361

Ответ 1

Когда вы пишете на трубку, которая была закрыта (удаленным концом), ваша программа получит этот сигнал. Для простых программ фильтрации командной строки это часто является подходящим действием по умолчанию, поскольку обработчик по умолчанию для SIGPIPE завершает работу программы.

Для многопоточной программы правильное действие обычно игнорирует сигнал SIGPIPE, поэтому запись в закрытый сокет не приведет к завершению работы программы.

Обратите внимание, что вы не можете успешно выполнить проверку перед записью, так как удаленный конец может закрыть сокет между вашей проверкой и вашим вызовом до write().

См. этот вопрос для получения дополнительной информации об игнорировании SIGPIPE: Как предотвратить SIGPIPE (или обрабатывать их правильно)

Ответ 2

Вы не поймаете SIGPIPE сигналы, но вы пытаетесь записать в трубу, которая была сломана/закрыта.

Довольно понятно.

Обычно достаточно обрабатывать сигналы SIGPIPE как no-op и обрабатывать случай ошибки вокруг вашего вызова write любым способом, который вам нужен... например это.