程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> LINUX系統編程 由REDIS的持久化機制聯想到的子進程退出的相關問題,linuxredis

LINUX系統編程 由REDIS的持久化機制聯想到的子進程退出的相關問題,linuxredis

編輯:關於C語言

LINUX系統編程 由REDIS的持久化機制聯想到的子進程退出的相關問題,linuxredis


19:22:01 2014-08-27

引言:

以前對wait waitpid 以及exit這幾個函數只是大致上了解,但是看REDIS的AOF和RDB 2種持久化時 均要處理子進程運行完成退出和父進程需要做的什麼事情,所以特定看了UNIX環境編程和LINUX系統編程這2本書 重新梳理下整個要點。

 

內容:

一般而言: 如果程序類似於下面的情況:

 

 
if((pid=fork())==0)
{
  dochildtthing();
 exit(0);      
}
else if(pid>0) 
{
 dofathertthing();
}    

 

  子進程就會調用了我們進程退出系統調用exit()分為2種狀態  0: 成功  非0:失敗

  exit需要做以下事情:

  1: 關閉所有打開的IO流

  2 刪除所有的臨時文件

  1 2是傳說中用戶態需要完成的事情  接下來就調用_exit() 【這個函數在用戶態下 是被exit()封裝起來的函數】觸發內核來完成進程退出的相關工作

  接下來就是清空所有的子進程所需要的資源哦 最後完成了 就會發送一個進程退出狀態【信號】給父進程  父進程做什麼處理就是編程人員完成的。

子進程發送的信號是SIGCHLD 一般而言就像REDIS fork()了一個進程之後  子進程完成了相應的持久化動作之後,父進程需要了解子進程一些狀態來做相應的處理工作,所以在LINUX系統中,這個子進程退出後 還有一個標記位 我們稱作zombie進程。父進程必須來取子進程的相應zombie的相應標記信息 不然是不會消除的。

所以對於父進程而言,必須調用相應的函數【首先是注冊了SIGCHLD】處理這些標記位哦  wait/waitpid就是干這種事情。我們來看看這系列的調用所要做的事情:

 

 1 #include <unistd.h>
 2 #include <stdio.h>
 3 #include <sys/types.h>
 4 #include <sys/wait.h>
 5 #include <stdlib.h>
 6 
 7 int main()
 8 {
 9     int status;
10     pid_t pid;
11     if(fork()==0)
12     {
13         abort();
14     }
15     pid=wait(&status);
16     printf("pid=%d\n",pid);
17     if(WIFEXITED(status))
18         printf("正常退出\n");
19     if(WIFSIGNALED(status))
20         printf("killed by signal\n");
21     return 0;
22 }

 

wait等待子進程掛  結果可以讀出子進程是被信號量終止了  所以說 讀出子進程的狀態還是非常有實際意義的~!

接下來看看wait/waitpid函數的區別:

如果有多個子進程 我該怎麼辦  要麼選擇多個wait 但是同時到達 可能就會處理一個子進程 而其他進程狀態沒有被處理  造成了很多zombie進程 這是不行的 這樣就有了waitpid函數:

 waitpid(pid_t pid,int *status,int options)

pid=-1  等待任意一子進程  

>0  要傳入的那個子進程

參數:

WNOHANG: 不會阻塞  立刻返回。 其他參數暫時不去研究了 

這樣如果有這種 while(waitpid(-1,&stat,WNOHANG)>0);

這樣就能接受到所有的子進程的SIGCHLD了。 wait只執行一次 而Linux信號不排隊 同時到達 也只會處罰一次哦 這個必須要了解 這樣通過waitpid循環來解決掉,但是如果不指定WNOHANG的話  又比較麻煩  主進程會阻塞 這不是我們所想要的哦 所以必須解阻塞。

 


redis選擇aof持久化的時 只可以用到一半的maxmemory?

可能在持久化操作時要用到fork出的新進程,子進程完全拷貝了父進程,maxmemory可能是指所有進程的memory,所以只有一半內存。
 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved