代碼#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
class ProcessMap
{
private:
map<std::string, pid_t> m_process_map;
public:
const bool create_process(const std::string& process_name, const std::string& user_name);
const bool remove_process(const std::string& user_name);
};
//create child process and add to process map
const bool ProcessMap::create_process(const std::string& process_name, const std::string& user_name)
{
QMServerMap::remove_process(user_name);
pid_t pID = fork();
if (pID == 0)
{
//you can add arguments for the child process if you like
execl(process_name, NULL);
}
else if (pID < 0)
{
// failed to fork
return false;
}
else
{
// parent
m_process_map[user_name] = pID;
}
return true;
}
//delete child process and remove from the process map
const bool QMServerMap::remove_process(const std::string& user_name)
{
if (m_process_map.find(user_name)!=m_process_map.end())
{
pid_t pid = m_process_map[user_name];
if (pid > 0)
{
kill(pid,SIGTERM);
waitpid(pid, NULL, 0);
}
m_process_map.erase(user_name);
return true;
}
return false;
}
1. 如果子進程未結束, 父進程仍在執行, kill 子進程之後, 調用waitpid 讀取子進程狀態, 可以避免僵死進程
2. 如果子進程已經退出, 父進程仍在執行且未調用remove process , 此時子進程為僵死進程, 可以通過調用 remove process 刪除僵死子進程
A better way to avoid zombie child process
代碼#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
class ProcessMap
{
private:
static map<std::string, pid_t> m_process_map;
public:
static void create_process(const std::string& process_name, const std::string& user_name);
static void remove_process(const std::string& user_name);
static void zombie_handler(int signal);
};
void ProcessMap::zombie_handler(int signal)
{
int status;
pid_t pid = wait(&status);
map<string, pid_t>::iterator iter;
for(iter = m_process_map.begin(); iter!=m_process_map.end(); ++iter)
if (iter->second == pid)
{
m_process_map.erase();
return;
}
}
//create child process and add to process map
void ProcessMap::create_process(const std::string& process_name, const std::string& user_name)
{
if (m_process_map.find(user_name)!=m_process_map.end())
return;
signal(SIGCHLD, zombie_handler);
pid_t pID = fork();
if (pID == 0)
{
//you can add arguments for the child process if you like
execl(process_name, NULL);
}
else if (pID < 0)
{
// failed to fork
return;
}
else
{
// parent
m_process_map[user_name] = pID;
}
}
//kill child process
void QMServerMap::remove_process(const std::string& user_name)
{
if (m_process_map.find(user_name)!=m_process_map.end())
kill(m_process_map[user_name],SIGTERM);
}
1. signal(SIGCHLD, zombie_handler) ; 註冊zombie_handler 來處理 子進程結束事件, 調用wait, 刪除zombie process