mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
解决defunct进程的问题
This commit is contained in:
parent
1f89a86892
commit
8e48ab3463
@ -34,9 +34,8 @@
|
|||||||
#include "Util/File.h"
|
#include "Util/File.h"
|
||||||
#include "Util/logger.h"
|
#include "Util/logger.h"
|
||||||
#include "Util/uv_errno.h"
|
#include "Util/uv_errno.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include "Thread/WorkThreadPool.h"
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
#include "Poller/Timer.h"
|
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
void Process::run(const string &cmd, const string &log_file_tmp) {
|
void Process::run(const string &cmd, const string &log_file_tmp) {
|
||||||
@ -46,12 +45,11 @@ void Process::run(const string &cmd, const string &log_file_tmp) {
|
|||||||
throw std::runtime_error(StrPrinter << "fork child process falied,err:" << get_uv_errmsg());
|
throw std::runtime_error(StrPrinter << "fork child process falied,err:" << get_uv_errmsg());
|
||||||
}
|
}
|
||||||
if (_pid == 0) {
|
if (_pid == 0) {
|
||||||
//子进程
|
|
||||||
|
|
||||||
//子进程关闭core文件生成
|
//子进程关闭core文件生成
|
||||||
struct rlimit rlim = {0,0};
|
struct rlimit rlim = {0,0};
|
||||||
setrlimit(RLIMIT_CORE, &rlim);
|
setrlimit(RLIMIT_CORE, &rlim);
|
||||||
|
|
||||||
|
//在启动子进程时,暂时禁用SIGINT、SIGTERM信号
|
||||||
// ignore the SIGINT and SIGTERM
|
// ignore the SIGINT and SIGTERM
|
||||||
signal(SIGINT, SIG_IGN);
|
signal(SIGINT, SIG_IGN);
|
||||||
signal(SIGTERM, SIG_IGN);
|
signal(SIGTERM, SIG_IGN);
|
||||||
@ -109,24 +107,73 @@ void Process::run(const string &cmd, const string &log_file_tmp) {
|
|||||||
InfoL << "start child proces " << _pid;
|
InfoL << "start child proces " << _pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::kill(int max_delay) {
|
|
||||||
|
/**
|
||||||
|
* 获取进程是否存活状态
|
||||||
|
* @param pid 进程号
|
||||||
|
* @param exit_code_ptr 进程返回代码
|
||||||
|
* @param block 是否阻塞等待
|
||||||
|
* @return 进程是否还在运行
|
||||||
|
*/
|
||||||
|
static bool s_wait(pid_t pid,int *exit_code_ptr,bool block) {
|
||||||
|
if (pid <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int status = 0;
|
||||||
|
pid_t p = waitpid(pid, &status, block ? 0 : WNOHANG);
|
||||||
|
int exit_code = (status & 0xFF00) >> 8;
|
||||||
|
if(exit_code_ptr){
|
||||||
|
*exit_code_ptr = (status & 0xFF00) >> 8;
|
||||||
|
}
|
||||||
|
if (p < 0) {
|
||||||
|
WarnL << "waitpid failed, pid=" << pid << ", err=" << get_uv_errmsg();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (p > 0) {
|
||||||
|
InfoL << "process terminated, pid=" << pid << ", exit code=" << exit_code;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//WarnL << "process is running, pid=" << _pid;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s_kill(pid_t pid,int max_delay,bool force){
|
||||||
|
if (pid <= 0) {
|
||||||
|
//pid无效
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (::kill(pid, force ? SIGKILL : SIGTERM) == -1) {
|
||||||
|
//进程可能已经退出了
|
||||||
|
WarnL << "kill process " << pid << " failed:" << get_uv_errmsg();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(force){
|
||||||
|
//发送SIGKILL信号后,阻塞等待退出
|
||||||
|
s_wait(pid, NULL, true);
|
||||||
|
DebugL << "force kill " << pid << " success!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//发送SIGTERM信号后,2秒后检查子进程是否已经退出
|
||||||
|
WorkThreadPool::Instance().getPoller()->doDelayTask(max_delay,[pid](){
|
||||||
|
if (!s_wait(pid, nullptr, false)) {
|
||||||
|
//进程已经退出了
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//进程还在运行
|
||||||
|
WarnL << "process still working,force kill it:" << pid;
|
||||||
|
s_kill(pid,0, true);
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Process::kill(int max_delay,bool force) {
|
||||||
if (_pid <= 0) {
|
if (_pid <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (::kill(_pid, SIGTERM) == -1) {
|
s_kill(_pid,max_delay,force);
|
||||||
WarnL << "kill process " << _pid << " falied,err:" << get_uv_errmsg();
|
|
||||||
} else {
|
|
||||||
//等待子进程退出
|
|
||||||
auto pid = _pid;
|
|
||||||
EventPollerPool::Instance().getPoller()->doDelayTask(max_delay,[pid](){
|
|
||||||
//最多等待2秒,2秒后强制杀掉程序
|
|
||||||
if (waitpid(pid, NULL, WNOHANG) == 0) {
|
|
||||||
::kill(pid, SIGKILL);
|
|
||||||
WarnL << "force kill process " << pid;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_pid = -1;
|
_pid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,28 +181,10 @@ Process::~Process() {
|
|||||||
kill(2000);
|
kill(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::Process() {
|
Process::Process() {}
|
||||||
}
|
|
||||||
|
|
||||||
bool Process::wait(bool block) {
|
bool Process::wait(bool block) {
|
||||||
if (_pid <= 0) {
|
return s_wait(_pid,&_exit_code,block);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int status = 0;
|
|
||||||
pid_t p = waitpid(_pid, &status, block ? 0 : WNOHANG);
|
|
||||||
|
|
||||||
_exit_code = (status & 0xFF00) >> 8;
|
|
||||||
if (p < 0) {
|
|
||||||
WarnL << "waitpid failed, pid=" << _pid << ", err=" << get_uv_errmsg();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (p > 0) {
|
|
||||||
InfoL << "process terminated, pid=" << _pid << ", exit code=" << _exit_code;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//WarnL << "process is running, pid=" << _pid;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::exit_code() {
|
int Process::exit_code() {
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
Process();
|
Process();
|
||||||
~Process();
|
~Process();
|
||||||
void run(const string &cmd,const string &log_file);
|
void run(const string &cmd,const string &log_file);
|
||||||
void kill(int max_delay);
|
void kill(int max_delay,bool force = false);
|
||||||
bool wait(bool block = true);
|
bool wait(bool block = true);
|
||||||
int exit_code();
|
int exit_code();
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user