C++ 使用system()创建独立的子进程
我编写了一个程序,在主线程中创建一个线程,并使用C++ 使用system()创建独立的子进程,c++,multithreading,pthreads,fork,system-calls,C++,Multithreading,Pthreads,Fork,System Calls,我编写了一个程序,在主线程中创建一个线程,并使用system()从该线程启动另一个进程。此外,我还使用main函数中的system()启动相同的过程。从线程启动的进程似乎保持活动状态,即使父进程死亡。但是从主函数调用的一个将随父函数一起消亡。你知道为什么会这样吗 请在下面查找代码结构: void *thread_func(void *arg) { system(command.c_str()); } int main() { pthread_create(&a
system()
从该线程启动另一个进程。此外,我还使用main函数中的system()
启动相同的过程。从线程启动的进程似乎保持活动状态,即使父进程死亡。但是从主函数调用的一个将随父函数一起消亡。你知道为什么会这样吗
请在下面查找代码结构:
void *thread_func(void *arg)
{
system(command.c_str());
}
int main()
{
pthread_create(&thread_id, NULL, thread_func, NULL);
....
system(command.c_str());
while (true)
{
....
}
pthread_join(thread_id, NULL);
return 0;
}
我的建议是:不要做你所做的。如果要创建独立运行的子进程,请研究和函数。这就是
系统
将使用的“发动机罩下”
线程并不像进程那样真正独立。当“主”进程结束时,所有线程也结束。在您的特定情况下,线程似乎继续运行,而主进程似乎由于pthread\u join
调用而结束,它只会等待线程退出。如果删除连接调用,线程(以及“命令”)将被终止
有一些方法可以分离线程,这样它们就可以更独立地运行(例如,您不必加入分离的线程),但主进程仍然无法结束,相反,您必须结束主线程,这将在分离的线程运行时保持进程运行
使用
fork
和exec
实际上非常简单,也不是很复杂:
int pid = fork();
if (pid == 0)
{
// We are in the child process, execute the command
execl(command.c_str(), command.c_str(), nullptr);
// If execl returns, there was an error
std::cout << "Exec error: " << errno << ", " << strerror(errno) << '\n';
// Exit child process
exit(1);
}
else if (pid > 0)
{
// The parent process, do whatever is needed
// The parent process can even exit while the child process is running, since it's independent
}
else
{
// Error forking, still in parent process (there are no child process at this point)
std::cout << "Fork error: " << errno << ", " << strerror(errno) << '\n';
}
intpid=fork();
如果(pid==0)
{
//我们在子进程中,执行命令
execl(command.c_str()、command.c_str()、nullptr);
//如果execl返回,则表示出现错误
std::cout这里有两点我认为您遗漏了:
首先,system
是一个同步调用。这意味着,您的程序(或者至少是调用system
的线程)等待子线程完成。因此,如果命令
长期运行,主线程和工作线程都将被阻塞,直到它完成
第二,你正在“加入”位于main
末尾的工作线程。这是正确的做法,因为除非您加入或分离线程,否则您的行为未定义。但是,这不是您真正想要做的。最终结果不是子进程在主进程结束后继续…您的主进程仍然处于活动状态!它在主进程上被阻止pthread\u join
调用,该调用正在尝试包装仍在运行的工作线程命令
一般来说,假设您希望生成一个与主进程完全无关的新进程,线程不是这样做的方式。即使您要分离线程,它仍然属于您的进程,并且您仍然需要让它在进程终止之前完成。您不能使用线程从进程分离
而不是需要OS特性,如<代码> Fooe<代码>和<代码> Exc< /Cube >(或围绕这个功能的友好C++包装,如Boosix.SuPalPosits)。这是唯一真正地从程序中产生新进程的方法。
但是,您可以作弊!如果命令
是一个shell命令,并且您的shell支持后台作业,那么您可以将&
放在命令末尾(这是Bash语法的一个示例),以进行系统
调用:
- 请壳牌公司衍生出一个新流程
- 等它这么做吧
- 新进程现在将继续在后台运行
例如:
const std::string command = "./myLongProgram &";
// ^
然而,同样,这是一种黑客攻击,为了获得最大的可移植性和可预测性,应该优先选择驻留在程序逻辑中的适当的fork机制。我同意答案。此外,如果您只需要捕获命令的输出,而不需要在主进程死亡后运行它,那么这很有用:@ErikAlapäGood链接。但公认的答案确实存在while(!feof(…)
循环的缺陷(如注释中所指出的)。我不需要双叉,因为我希望父进程继续,而不是等待子进程。@yashkapor除非您想获得子进程的退出状态,否则您永远不需要等待它。如果子进程成为孤立进程,则“init”进程将作为父进程接管,并在子进程结束时收获它。@某个程序员我尝试了您发布的上述代码示例。因此,每当我使用Ctrl+C终止父进程时,子进程也会放弃您对thread\u func()的定义
不正确-它缺少参数。请看哪个示例。@kiner_shah这只是一个骨架。我的实际代码中确实有这个东西