C – 使用fork()和exec()两次

我有以下代码:

int main(int argc, char **argv) { char *program; char stringa[1000] = ""; int num = 123; char snum[10]; if (argc != 2) { printf("Usage: mon fileName\n where fileName is an executable file.\n"); exit(-1); } else { program = argv[1]; sprintf(stringa, "./%s", program); pid_t pid = fork(); if (pid < 0 ) { perror("fork failed."); exit(1); } else if (pid == 0) { char* args[] = {stringa, NULL}; execv(args[0], args); } else { char procmon_str[] = "./procmon"; num = pid; sprintf(snum, "%d",num); pid_t pid2 = fork(); if (pid2 == 0) { char* args2[] = {procmon_str, snum, NULL}; execv(args2[0], args2); } else { printf("PID of child is %s", snum); int parent_pid = getpid(); printf("PID of parent is %d", parent_pid);} }} wait(NULL); return 0; } 

这个程序的名字是myProgram 。 我在shell中提供的参数是:

 ./myProgram calc 

calc是我想用myProgram启动的另一个程序。 然后myProgram执行calc ,取其PID并将该PID传递给另一个称为procmon程序, 这就是为什么我需要分叉两次。 但是,当我运行上面的代码时,我得到:

procmon: cannot open /proc/6225/stat, the monitored process is not running anymore

我怎样才能解决这个问题?

calc是什么? 它进入for循环,递增一个intvariables,并进入睡眠3秒钟,并重复10次。 所以它应该运行约30秒。

什么procmon做? procmon只是接收一个进程的PID作为参数,并显示相应的/proc/PID/stat文件。 当你自己运行时,它是完美的。

你有一个竞争条件。 您不能保证在calc子进程完成执行和退出之前,第一个fork()实际上甚至会返回到父进程。 您需要同步流程的执行。

ETA建议在哪里阻止和信号

 if (pid == 0) { // block here waiting for the go-ahead from parent char* args[] = { stringa, NULL }; execv( args[ 0 ], args ); } ...... else { // signal calc child here printf( "PID of child is %s", snum ); int parent_pid = getpid(); printf( "PID of parent is %d", parent_pid ); } 

学习如何通过进程间通信进行阻止和发送信号作为询问者的练习。

起初没有注意到…

你的主要过程是创建两个子进程,proc和prcmon。 你的问题是,由于竞争条件和调度 – calc首先完成,所以你想要做的是强制calc等待其兄弟进程。 你只能等待()你创建的进程…所以这样你就不能让calc等待prcmon完成。

您可以实现一些机制来使父进程等待其子进程,然后通过管道将返回数据传递给其他子进程。 在你的情况下,我不知道。 你想在prcmon得到calc的PID并显示它? 我不知道这是否是可能的,因为一旦calc完成,其描述符被擦除并且不再存在。

你的问题的一个解决办法是使计算繁重的计算,因为你只需要它活着,而不是它的返回值。

所以没有注意到,我的程序提供了正确的输出。 我的程序叫做myProgram ,它是这样启动的:

 ./myProgram calc 

其中calc是一个运行30秒的程序,进行一些基本的数学运算,没有什么太疯狂的。 然后,另一个进程procmon启动。 procmon获取calcPID并打印文件:

 /proc/calc-PID/stat 

这到底是怎么回事 我收到了这个文件到我的shell,这意味着calcprocmon都能成功运行。 出于某种原因,我以为我应该在系统运行这个程序后得到一个新的文件,所以我甚至没有注意到在shell中发生了什么。

对于某些人可能造成的困惑,我深表歉意,我一定要记住在问之前多检查一次我的问题。

我也非常感谢大家的帮助和支持,成为这个社区的一员真是太棒了!