Linuxマシンでepollを使用してネットワークプログラムに取り組んでいますが、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;
}
(リモートエンドによって)閉じられたパイプに書き込むと、プログラムはこの信号を受信します。単純なコマンドラインフィルタープログラムの場合、これは多くの場合、適切なデフォルトアクションです。これは、SIGPIPEのデフォルトハンドラーがプログラムを終了するためです。
マルチスレッドプログラムの場合、正しいアクションは通常、SIGPIPE信号をignoreすることです。これにより、閉じたソケットに書き込んでもプログラムは終了しません。
リモートエンドがチェックとwrite()
の呼び出しの間のソケットを閉じる可能性があるため、書き込みの前にチェックを正常に実行できないことはできないことに注意してください。 。
SIGPIPEを無視する方法の詳細については、この質問を参照してください。 SIGPIPEを防止する(または適切に処理する)方法