C - using fork () and exec () twice

I have the following code:

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; } 

The name of this program is myProgram . The argument I provide in the shell is:

 ./myProgram calc 

calc is another program that I want to run using myProgram . myProgram then performs calc , takes its PID and passes that PID to another program called procmon , which does something with it; so i need to deploy twice. However, when I run the code above, I get:

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

How can i fix this?

What does calc do? It goes into the for loop, increments the int variable and goes into sleep mode for 3 seconds and repeats this 10 times. Therefore, it should work for about 30 seconds.

What does procmon do? procmon simply takes the process PID as an argument and displays the corresponding file /proc/PID/stat . It works great when you run it yourself.

+8
c linux
source share
3 answers

You have a race condition. You have no guarantee that the first fork() actually even return to your parent process before the calc child process completes and exits. You need to synchronize the execution of your processes.

ETA suggestions on where to block and signal

 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 ); } 

Learning how to block and signal through interprocess communication remains as an exercise for the questioner.

+5
source share

Did not notice at first ...

Your main process is creating two child processes, proc and prcmon. Your problem is that because of the conditions of the race and the calculation, the clipping ends first, so what do you want to do to make calc wait for its related process. You can only wait () in the process you created ... Thus, you cannot make calc wait for prcmon to complete.

BUT

You can implement some mechanism to make the parent process wait for its children, and then pass the returned data through the pipe to another child process. In your case, I'm not sure. Do you want prcmon to get PID calc and display it? I do not know if this is possible, as soon as the calculation is done, its handle is erased and no longer exists.

The solution to your problem is to make calc do a heavy calculation, since you only need the live value and not its return value.

+2
source share

Therefore, without noticing, my program provided the correct exit. My program is called myProgram and runs as follows:

 ./myProgram calc 

Where calc is a program that runs for 30 seconds, performing some basic math operations, nothing crazy. Then another procmon process procmon . procmon takes the PID in calc and prints the file:

 /proc/calc-PID/stat 

This is exactly what happened. I got this file for my shell, which means that both calc and procmon successfully. For some reason, I thought that I had to get a new file in the system after running this program, so I did not even pay much attention to what was happening in the shell.

I really regret any confusion that this could cause some people, I will definitely remember my problem 1000 more times before asking.

I am also very grateful to everyone for their help and support, it is great to be part of this community!

0
source share

All Articles