在微服务架构下,会涉及到大量的模块,我们需要对这些模块进行批量化的管理,包括模块的启动、监控等工作。
方案一
#include <syslog.h> #include <fcntl.h> #include <sys/resource.h> #include <sys/sysinfo.h> #include <unistd.h> #include <string> #include <iostream> #include <sys/stat.h> int main() { pid_t pid = 0; //创建一个子进程,fork()函数没有参数。 pid = fork(); if (pid < 0) { std::cout << "error" << std::endl; } else if (0 != pid) { pause(); } setsid(); umask(0); // //关闭文件描述符 int des=getdtablesize(); int i=0; for(i=0;i<3;i++) { close(i); } //子进程得到的返回值是0,这段代码在子进程中执行 std::string strTp = "./binname"; execl(strTp.c_str(), strTp.c_str(), "-cmd", "value", nullptr); return 0; }
该方法虽然可以正常创建进程,但创建的进程与当前进程存在父子关系,当前进程异常可能会导致子进程异常,所以这种办法并不可取。
方案二
int main() { pid_t pid = 0; //创建一个子进程,fork()函数没有参数。 pid = fork(); if (pid < 0) { std::cout << "error" << std::endl; } else if (0 != pid) { pause(); } setsid(); umask(0); //关闭文件描述符 int des=getdtablesize(); int i=0; for(i=0;i<3;i++) { close(i); } if ((pid = fork()) < 0) std::cout << "error" << std::endl; else if (pid != 0) /* parent */ exit(0); //子进程得到的返回值是0,这段代码在子进程中执行 std::string strTp = "./binname"; execl(strTp.c_str(), strTp.c_str(), "-cmd", "value", nullptr); return 0; }
该方法是在子进程中创建孙进程来作为执行模块,然后子进程退出,孙进程会变成孤儿进程,由系统接管。
方案三
int fnProcess(void *stack) { std::tuple<std::string, std::string, std::string> *pArg = static_cast<std::tuple<std::string, std::string, std::string> *>(stack); std::string strTp, strUuid, strServerName; std::tie(strTp, strUuid, strServerName) = *pArg; setsid(); //子进程得到的返回值是0,这段代码在子进程中执行 execl(strTp.c_str(), strTp.c_str(), "-u", strUuid.c_str(), "-s", strServerName.c_str(), nullptr); delete pArg; return 1; } int main() { void * stack; stack = malloc(FIBER_STACK);//为子进程申请系统堆栈 if (!stack) { printf("The stack failed\n"); exit(0); } std::tuple<std::string, std::string, std::string> *pArg = new std::tuple<std::string, std::string, std::string>(strTp, strUuid, strServerName); clone(&fnProcess, (char *)stack + FIBER_STACK, CLONE_PARENT, pArg);//创建子线程 }
该方案通过手动分配堆栈,将信息传递给子进程来实现精准控制。