-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathWorkerProcess.cpp
118 lines (106 loc) · 3.26 KB
/
WorkerProcess.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
NAME
WorkerProcess.hpp - Body file of the Worker Process class.
DESCRIPTION
Worker Process.
工作进程类
*/
#include "WorkerProcess.hpp"
#include "Configure.hpp"
#include "Logger.hpp"
#include <cstring>
#include <iterator>
#include <unistd.h>
#include <sys/types.h>
WorkerProcess::WorkerProcess() { }
// 构造函数
WorkerProcess::WorkerProcess(std::string name, std::string command, std::string work_dir, bool auto_start)
{
if(auto_start) {
_pid = -1;
} else {
_pid = 0;
}
_name = name;
_command = command;
_work_dir = work_dir;
std::istringstream iss(_command);
std::string token;
while(iss >> token) {
_tokens.push_back(token);
}
}
// 析构函数
WorkerProcess::~WorkerProcess() { }
// 启动工作进程
bool WorkerProcess::launch() {
if(_pid < 0) {
const char **argv = new const char*[_tokens.size() + 1]; // execvp()函数最后的一个参数需要是NULL
for (std::vector<std::string>::size_type i = 0; i < _tokens.size() + 1; ++i) {
argv[i] = _tokens[i].c_str();
}
argv[_tokens.size()] = NULL;
LOG_DEBUG_MSG("Starting worker:[" + _name + "] process using command:[" + _command + "].");
_pid = fork();
switch(_pid) {
case -1: // 创建新进程失败
LOG_ERROR_MSG("Error creating child process using fork.");
break;
case 0: // 子进程
Logger::stop();
// 关闭无效的文件句柄,父进程打开了一个UNIX socket
for(int x = sysconf(_SC_OPEN_MAX); x > 0; x--) {
close(x);
}
Logger::start(Configure::get_log_dir() + _name + ".out");
if(chdir(Configure::get_work_dir().c_str()) != 0) {
LOG_ERROR_MSG("Cannot change to the daemon work directory.");
}
if(!_work_dir.empty()) {
if(chdir(_work_dir.c_str()) != 0) {
LOG_ERROR_MSG("Cannot change to the work directory:[." + _work_dir + "].");
}
}
if(execvp(argv[0], (char**) argv) < 0) {
LOG_ERROR_MSG("Error executing command:[" + _command + "].");
_pid = 0;
exit(EXIT_FAILURE);
}
break;
default: // 父进程
LOG_INFO_MSG("Worker:[" + _name + "] process with command:[" + _command + "] now running PID:[" + std::to_string(_pid) + "].");
}
}
return (_pid > 0);
}
// 如果工作进程原PID为old_pid,需要重启动它
void WorkerProcess::relaunch(int old_pid) {
if(_pid == old_pid) {
_pid = -1;
LOG_DEBUG_MSG("Worker process with PID:[" + std::to_string(old_pid) + "] will be relaunch.");
}
}
// 获取工作进程当前的PID
pid_t WorkerProcess::get_pid()
{
return _pid;
}
// 设置工作进程的PID
void WorkerProcess::set_pid(pid_t pid)
{
_pid = pid;
}
// 设置工作进程的命令
void WorkerProcess::set_command(std::string command) {
if(_command.compare(command) != 0) {
LOG_INFO_MSG("Worker:[" + _name + "] process changed command from:[" + _command + "] to:[" + command + "].");
_command = command;
}
}
// 设置工作进程的工作目录
void WorkerProcess::set_work_dir(std::string work_dir) {
if(_work_dir.compare(work_dir) != 0) {
LOG_INFO_MSG("Worker:[" + _name + "] process changed command from:[" + _work_dir + "] to:[" + work_dir + "].");
_work_dir = work_dir;
}
}