让我们说我运行了一个简单的后台流程:
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。有人可以帮忙吗?
答案 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。但是,如果您拨打system
或popen
,则不会,因为这些功能fork
新进程本身。谈论system
,如果你把它放在自己的进程中,那么你不需要使用&
在后台运行,子进程本身确保命令已经在后台。
答案 2 :(得分:1)
阅读C shell considered harmful,然后切换到一个不错的交互式shell(例如zsh,fish,bash)。对于脚本,请考虑Posix sh
(或使用真正的脚本语言)。
阅读Advanced Linux Programming(其中大部分内容对其他Unix系统都有价值,包括Solaris)。
您应该了解如何使用fork(2),getpid(2),execve(2),pipe(2),waitpid(2)等...(这些标准由{{3标准化}})。我们不能花费数小时教你这些,但你绝对应该阅读有关它们的书籍。了解POSIX的工作方式很棘手。
您可能需要调用fork函数或sleep(3)系统调用。你不应该使用system
或popen
来sleep
(两者都会分叉一个shell进程,在这种情况下没用),只需调用函数!
不要忘记nanosleep(2)是stdio(3)。你可能需要明智地(特别是在std::flush
之前)在C ++中调用buffered(在C中)或fork
。
答案 3 :(得分:1)
正如其他人所指出的,你为sleep命令显示的PID是睡眠命令本身的PID(即你所说的你需要的)。因此,您从过程中打印出来的PID是27464,而您使用system()创建的睡眠的PID是27466.也许如果您更多地了解您尝试做什么,我们可以提供更多帮助。