Linux上でmain()と2つのpthreadが作成されたCプログラムを作成しています。 pthreadの1つでは、accept()関数を呼び出す必要があります。SA_RESTARTフラグが0に設定されていても、SIGINTが発生したときにaccept()が再開します。
私はSIGINT、SIGQUITまたはSIGTERMの受信時に呼び出されるシグナルハンドラを持っています。
私はctrl-cを押したときにaccept()関数がEINTRを返すのではなく、SA_RESTARTフラグを0にしているので、デバッグ中にprintf呼び出しを束ねて実現しました私のアプリケーションがSIGINTを捕まえることができても、accept関数はブロックされたままであり、EINTRで失敗しておらず、次のコード行に移動していないことに注意してください。ここで
void terminate (int signum)
{
terminate_program = 1;
printf("Terminating.\n");
}
は受け入れる()呼び出しが(私が作るために無関係なものを削除しようとした作られpthreadのである:ここでは はここ
struct sigaction signal_action;
signal_action.sa_flags = 0; // Don't restart the blocking call after it failed with EINTR
signal_action.sa_handler = terminate;
sigemptyset(&signal_action.sa_mask);
sigfillset(&signal_action.sa_mask); // Block every signal during the handler is executing
if (sigaction(SIGINT, &signal_action, NULL) < 0) {
perror("error handling SIGINT");
}
if (sigaction(SIGTERM, &signal_action, NULL) < 0) {
perror("error handling SIGTERM");
}
if (sigaction(SIGQUIT, &signal_action, NULL) < 0) {
perror("error handling SIGQUIT");
}
は、シグナルハンドラである)(メイン内部の私の設定です私の質問が分かりやすい):
void* pthread_timerless_socket_tasks(void* parameter)
{
server_socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(server_socket_fd < 0)
{
perror("error creating IPv4 TCP stream socket");
return (NULL);
}
printf("socket created\n"); // for debugging
if(fcntl(server_socket_fd, F_SETFL, 0) < 0)
{
perror("error making socket_fd blocking");
close(server_socket_fd);
return (NULL);
}
while(!terminate_program)
{
printf("socket blocking on accept\n"); // for debugging
client_socket_fd = accept(server_socket_fd,(struct sockaddr *) &client_address, &client_length);
printf("socket accepted?\n"); // for debugging
if(client_socket_fd < 0)
{
perror("error accepting socket_fd");
close(server_socket_fd);
return (NULL);
}
}
私は自分自身を明確にしたいと思います。
これで、SA_RESTARTのLinuxマニュアルに記載されている動作を確認できないため、不足しているものや間違っているものが見つかりました。
このfcntl(server_socket_fd、F_SETFL、0)...は間違っていると思われます。 – alk
@alk私はファイルディスクリプタをこのようにブロックしようとしていましたが、デフォルトではそうではありませんでした。私は提案にオープンしています:) – etugcey
'fcntl()'を使ってソケットのブロッキング状態を切り替える方法については、この回答をご覧ください:http://stackoverflow.com/a/1549344/694576 – alk