获取使用C ++在后台执行的命令的实际进程ID

时间:2013-11-22 06:53:07

标签: c++ c process solaris

让我们说我运行了一个简单的后台流程:

sleep 25 &

我在命令行上执行它:

> sleep 25 &
[1] 26390
> ps
   PID TTY         TIME CMD
 26390 pts/52      0:00 sleep
  6746 pts/52      0:02 tcsh
 26391 pts/52      0:00 ps
> 

您可以看到睡眠正在后台执行pid 26390 现在我尝试使用c ++做同样的事情。有许多不同的系统调用来做到这一点。

using system
using fork
using pipe

我尝试了以下代码:

if(p=fork()){
//Main process
cout<<p<<endl;
}
else{
execv("sleep 20 &",(char **)NULL);
}
}

输出是:

> ./a.out
27391
> ps
   PID TTY         TIME CMD
  6746 pts/52      0:02 tcsh
 27392 pts/52      0:00 ps
> 

您可以看到后台没有睡眠。 现在我尝试了另一种方式:

FILE* pipe = popen("sleep 20 &", "r");
    if(pipe){
                char buffer[128];
                while(fgets(buffer, 128, pipe));
                cout<<buffer<<endl;
                pclose(pipe);
             }

这会挂起20秒,我将永远不会使用进程ID打印该cout。

> ./a.out

> 

我再次尝试了另一种方式:

if(p=fork()){
//Main process
cout<<p<<endl;
}
else{
system("sleep 20 &");
}
}

> ./a.out
27464
> ps
   PID TTY         TIME CMD
 27466 pts/52      0:00 sleep
 27467 pts/52      0:00 ps
  6746 pts/52      0:02 tcsh

现在您可以看到睡眠在后台运行但具有不同的PID。

但我需要的是在后台执行的sleep命令的实际pid。 我坚信应该有一些方法可以在c ++的后台运行进程的确切pid。有人可以帮忙吗?

4 个答案:

答案 0 :(得分:4)

您要打印的进程ID是正确的。问题是您的睡眠无法正常启动。

没有必要拥有'&amp;'在睡觉的论点;你的代码已经这样做了。如果你有“&amp;”睡眠可能会抱怨,因为'&amp;'不是持续时间。

尝试这样的exec调用:

execlp("sleep", "sleep", "20", 0);

这将在PATH中的目录中搜索名为“sleep”的文件,并将当前进程替换为使用参数“sleep”和“20”调用的进程。这些参数使用argv和argc传递给main()。

阅读exec的手册页以获取更多详细信息。

答案 1 :(得分:1)

exec系列函数不接受shell命令,并且它们不启动shell。相反,他们用从磁盘加载的进程替换进程。使用execv函数的方式会失败。

另一方面,system函数实际上启动了一个shell来运行命令。

获取进程pid的方法非常简单:使用getpid函数。如在

std::cout << "pid = " << getpid() << '\n';

如果在正确调用exec函数之前分叉并使用上述内容,则会显示正在休眠的进程的pid。但是,如果您拨打systempopen,则不会,因为这些功能fork新进程本身。谈论system,如果你把它放在自己的进程中,那么你不需要使用&在后​​台运行,子进程本身确保命令已经在后台。

答案 2 :(得分:1)

阅读C shell considered harmful,然后切换到一个不错的交互式shell(例如zshfishbash)。对于脚本,请考虑Posix sh(或使用真正的脚本语言)。

阅读Advanced Linux Programming(其中大部分内容对其他Unix系统都有价值,包括Solaris)。

您应该了解如何使用fork(2)getpid(2)execve(2)pipe(2)waitpid(2)等...(这些标准由{{3标准化}})。我们不能花费数小时教你这些,但你绝对应该阅读有关它们的书籍。了解POSIX的工作方式很棘手。

您可能需要调用fork函数或sleep(3)系统调用。你不应该使用systempopensleep(两者都会分叉一个shell进程,在这种情况下没用),只需调用函数!

不要忘记nanosleep(2)stdio(3)。你可能需要明智地(特别是在std::flush之前)在C ++中调用buffered(在C中)或fork

答案 3 :(得分:1)

正如其他人所指出的,你为sleep命令显示的PID是睡眠命令本身的PID(即你所说的你需要的)。因此,您从过程中打印出来的PID是27464,而您使用system()创建的睡眠的PID是27466.也许如果您更多地了解您尝试做什么,我们可以提供更多帮助。