开发者

c / fork / signals / best practice closing open sockets in different processes

Hallo erveyone,

two days before I was asking about threads and fork. Now I ended up using the fork methods. Creating a second process, parent and child are executing different code, but both end up in a while loop, because one is sending forever packets through a socket and the other one is listening forever on a socket. Now I want them to clean up, when ctrl-c is pressed, i.e. both should close their open sockets before returning.

I have three files, first one, the main file creates the processes. In the second file is written the parent code, in the third the child code. Some more information (code snippets) you can find here: c / interrupted system call / fork vs. thread

Now my question, where do I have to put the signal handler, or do I have to specify two of them, one for each process? It seems like a simple question, but not for me somehow. I tried different ways. But could only make one of the guys successful to clean up before returning (my English is bad, sorry therefore). both have to do different things, that's the problem for me, so one handler wouldn't be enough, right?

struct sigaction new_action;
new_action.sa_handler = termination_handler_1;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction(SIGINT, &new_action, NULL);

....more code here ... 

/* will run until crtl-c is pressed */
while(keep_going) {
    recvlen = recvfrom(sockfd_in, msg, itsGnMaxSduSize_MIB, 0, (struct sockaddr *) &incoming, &ilen);
开发者_如何学JAVA    if(recvlen < 0) {
        perror("something went wrong / incoming\n");
        exit(1);
    }

    buflen = strlen(msg);
    sentlen = ath_sendto(sfd, &athinfo, &addrnwh, &nwh,  buflen, msg, &selpv2, &depv);

    if(sentlen == E_ERR) {
        perror("Failed to send network header packet.\n");
        exit(1);
    }
}

close(sockfd_in);
/* Close network header socket */
gnwh_close(sfd);
/* Terminate network header library */
gnwh_term();
printf("pc2wsu: signal received, closed all sockets and so on!\n");
return 0;
}


void termination_handler_1(wuint32 signum) {
    keep_going = 0;
}

As you can see, handling the signal in my case is just changing the loop condition "keep_going". After exiting the loop, each process should clean up.

Thanks in advance for your help. nyyrikki


There is no reason to close the sockets. When a process exits (as is the default action for SIGINT), all its file descriptors are inherently closed. Unless you have other essential cleanup to do (like saving data to disk) then forget about handling the signal at all. It's almost surely the wrong thing to do.


Your code suffers from a race condition. You test for keep_going and then enter recvfrom, but it might have gotten the signal between then. That is pretty unlikely, so we will ignore it.

It sounds like the sender and receiver were started by the same process and that process was started from the shell. If you have not done anything, they will be in the same process group and all three processes will receive SIGINT when you hit ^C. Thus it would be best if both processes handled SIGINT if you want to run cleanup code (note closing FDs isn't a good reason...the fds will be autoclosed when the process exits). If these are TCP sockets between the two, closing one side would eventually cause the other side to close (but for sender, not until they try to send again).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜