![](/img/trans.png)
[英]How can child kill parent process while parent process waits until child process to terminate?
[英]Parent process in server stuck in accept call. How do I terminate the parent cleanly from child
你好初学C程序员。
我有一个简单的服务器客户端设置。 我只希望一个客户端连接到服务器,但我希望其他客户端能够尝试获取服务器被占用的消息。
我能够通过一个客户端连接到服务器,并让其他尝试连接的客户知道没有空间。 当客户端告诉服务器关闭时,我的问题出现了。 子进程能够突破循环并终止。 但是,父节点无法使用管道从子节点接收消息,因为它一直处于accept
。
我可以使用kill(2)
来结束父节点,但是我会在关闭套接字和文件后得到一个干净的终止吗?
我也尝试让父母不要停止接受使用fcntl(sock_desc, F_SETFL, fcntl(sock_desc, F_GETFL, 0) | O_NONBLOCK);
但这开辟了新的问题。
我想以某种方式让孩子告诉父母跳过accept
行并继续,以便它获取管道消息并退出循环。
如果这是终止服务器的坏方法,我将不胜感激。
简化的服务器代码:
void termination_handler (int signum)
{
if(signum == SIGTERM){
//Is this where the accept call is changed?
}
}
void main(){
struct sigaction sa = {0}; //2b) Initialise the struct sigaction variable to all 0s beforehand.
sa.handler = termination_handler; //2a) Set the member for handler (to the signal-handler function)
sigaction(SIGTERM, &sa, NULL);
pid_t pid;
int loop = 1;
while(loop){
int sock = accept(net_sock, NULL, NULL); //After connection
//parent is stuck here
if(kill(pid,0) == -1){
pid = fork();
}
else{
//Tell second client there is no room and close socket
}
//Child
if(pid == 0){
while(loop){
//Read signal in from client to end child loop and terminate child
//Write with pipe to parent to end parent loop and terminate parent
kill(getppid(), SIGTERM) // Is this how I do it?
}
}
//Parent
else{
close(sock);
//Read with pipe from child to end loop
//After first connection, the parent won't get this message
}
}
操作系统将为您关闭文件描述符。 除非您有其他清理工作要做(例如写入文件或删除某些文件),否则使用未处理的终止信号(例如, SIGTERM
或SIGINT
)进行终止就足够了。
如果你还有其他清理工作要做,请让孩子用父母信号处理器建立一个信号的父母信号(你需要用sigaction
建立处理程序)。 这将使用返回码-1
和errno == EINTR
打破accept
,允许您做任何您需要做的事情。
volatile sig_atomic_t usr1 = 0;
void usr1_handler(int Sig) { usr1 = 1; }
//...
int main() { //...
sigaction(SIGUSR1, &(struct sigaction){.sa_handler=usr1_handler},0);
//...
usr1 = 0;
sock = accept( /*... */ );
if ( -1 == sock && EINTR == errno && usr1 ) //was interrupted by USR1
/* cleanup and exit */;
让孩子在结束之前发信号通知它的父母。 如果正确完成, accept()
将返回信号接收,返回-1
并将errno
为EINTR
。
来自accept()
的文档 :
返回值
成功完成后, accept()将返回已接受套接字的非负文件描述符。 否则,应返回-1,设置errno以指示错误,[...]
[...]
错误
如果出现以下情况,accept()函数将失败:
[...]
[EINTR] accept()函数被有效连接到达之前捕获的信号中断。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.