![](/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.