从多线程程序调用system() 我们正在研究一个用C++编写的多线程内存消耗应用程序。 我们必须执行大量shellscript/linux命令(并获取返回代码)

从多线程程序调用system() 我们正在研究一个用C++编写的多线程内存消耗应用程序。 我们必须执行大量shellscript/linux命令(并获取返回代码),c,linux,pthreads,system,fork,C,Linux,Pthreads,System,Fork,在阅读之后,我们清楚地认识到在我们的上下文中使用system()是个坏主意 解决方案是在程序启动后和创建任何线程之前进行fork 但与该过程的通信可能并不容易(插座、管道?) 我们考虑的第二个解决方案可能包括一个用python编写的专用deamon(使用xinetd?),它将能够处理我们的系统调用 你有过这个问题吗?你是怎么解决的 注: 下面是一篇更完整的文章来解释这个问题: 他们建议使用posix_spawn,它使用vfork()而不是fork()(在system()中使用)。您将遇到关于如何

在阅读之后,我们清楚地认识到在我们的上下文中使用system()是个坏主意

解决方案是在程序启动后和创建任何线程之前进行fork 但与该过程的通信可能并不容易(插座、管道?)

我们考虑的第二个解决方案可能包括一个用python编写的专用deamon(使用xinetd?),它将能够处理我们的系统调用

你有过这个问题吗?你是怎么解决的

注: 下面是一篇更完整的文章来解释这个问题:
他们建议使用posix_spawn,它使用vfork()而不是fork()(在system()中使用)。

您将遇到关于如何调用外部程序的问题(fork/exec/wait,how else),但这只是问题的一部分。我想,真正的问题是这个的调度,您不想并行运行太多的外部程序

在不知道线程组织在您的系统中是如何进行的情况下,我可以警告您两个问题

一个重要的问题是通过限制外部命令/脚本调用来保持低负载。您可以设置一个参数,它告诉您应该同时运行多少个并行外部命令。在调用外部命令之前,应该增加一个变量,该变量显示活动外部进程的数量;如果超出限制参数,请选择sleep()并重试。过程完成后,减小该变量。(必须禁用递增和递减。)


另一个问题是,当您使用外部程序时,管理其生命周期。您应该为每个外部进程设置一个“超时”,并在它挂起一段时间后将其杀死。应该有一个“超时”线程(或者应该是主线程),它控制其他线程。

您链接到的文章主要讨论fork()时的问题,而不是立即使用exec*()。由于system()通常由fork()和exec()实现,因此大多数问题不适用。然而,一个确实适用的问题是关于关闭文件描述符的问题;除非您有特定的理由不这样做,否则默认情况下使用O_CLOEXEC打开文件可能是一个很好的经验法则

大型内存消耗应用程序的fork()+exec()的一个问题是,如果操作系统配置为不允许内存过度使用,fork()可能会失败。解决这个问题的一个方法是在开始在主进程中分配大量内存之前,派生一个“外部进程处理程序”进程


最好的解决方案是,如果您需要的功能作为库提供,那么首先就不需要fork。不过,这在短期内可能不会温暖你的心。

这个解决方案怎么样:

在程序的一开始就使用fork(),并让孩子专注于启动和管理外部程序。然后让父进程启动其所有线程并执行应用程序逻辑,在需要外部进程时通过管道发送请求


这将在启动线程之前解决线程的问题。

将外部程序的运行称为“系统调用”可能不是一个好主意。在C和C++中,系统调用通常意味着与内核对话,即直接执行OS级调用。它是关于
fork()
即使父进程是多线程的,也会生成单线程子进程,并且没有说
system()
是个坏主意。system()执行fork(),然后执行()cf手册页:(
fork
通常不会因为overmit=0而失败,因为页面仍然是共享的(至少,直到它们开始分离)@jørgensen:问题是,禁用了Overmit后,操作系统必须确保有足够的空间,以防分叉进程决定写入其所有可写页面,因为操作系统不能先验地假设进程不会这样做。@jørgensen:
fork()
如果认为没有足够的内存(物理+交换),则会失败。