SIGPIPE, Сломанная труба - PullRequest
14 голосов
/ 26 июля 2011

Я работаю над сетевой программой, использующей 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 ?? ()

Мой сервер вычисляет время ^ 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;
        }

Ответы [ 2 ]

28 голосов
/ 26 июля 2011

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

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

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

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

2 голосов
/ 26 июля 2011

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

Совершенно очевидно.

Обычно достаточно обрабатывать сигналы SIGPIPE в режиме бездействия и обрабатывать ошибку вокруг вашего write вызова любым подходящим для вас способом ... как this .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...