Reputation: 6393
Program Description:
I am working on a program to help teach me about processes in C and Linux. The program uses fork
to create a child process and then the parent and the child both print out a message a certain amount of times saying Parent Process
, Child Process
accordingly. To keep things from being scrambled the parent waits for the child process to print all it's messages. To make things even more interesting the child process uses execv
to call another program that prints it's messages.
From what I've read on execv
a new process is not started; the new process image overlays the original process image. So when the child process starts the new program the process id inside that new program should be the same as the childs process id which is zero.
Problem:
When I print out the child's process id before calling execv
it is zero (as expected) but as soon as I get into the new program I print out the process id and it is the parents process id (but it should be the childs id).
Could anyone please explain why the new program does not have zero as the process id?
Arguments:
Argv[1]
= Number of times the message prints for the child processArgv[2]
= Number of times the message prints for the parent processArgv[3]
= Number of seconds waited after a message for the child processArgv[4]
= Number of seconds waited after a message for the parent processArgv[5]
= Message sent to the new program the child process starts (child processes message to be printed).Initial Program:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int arg, char *argv[]) {
if(arg < 6) {
printf("\n\t(Task4.c) Please provide the right arguments\n\n");
exit(EXIT_FAILURE);
}
char *argv2[3];
argv2[0] = argv[1];
argv2[1] = argv[3];
argv2[2] = argv[5];
int Nc = atoi(argv[1]);
int Np = atoi(argv[2]);
int Tc = atoi(argv[3]);
int Tp = atoi(argv[4]);
int n, exit_code;
pid_t pid;
char *message;
printf("\n\n(Task4.c)\tfork program starting\n");
pid = fork();
//Let child go first before the parent
if(pid != 0) {
int stat_val;
pid_t child_pid;
child_pid = wait(&stat_val);
printf("\n(Task4.c)\tChild has finished: PID = %d\n", child_pid);
if(WIFEXITED(stat_val))
printf("(Task4.c)\tChild exited with code %d\n\n", WEXITSTATUS(stat_val));
else
printf("(Task4.c)\tChld terminated abnormally\n");
}
//Set up the values for the parent and child
switch(pid)
{
case -1:
perror("(Task4.c)\tfork failed");
exit(1);
case 0:
/* a child execute different program */
printf("\n(Task4.c)\tpid=%d\n\n", pid);
if (execv ("child", argv2) <0)
{
printf ("(Task4.c)\texecl ERROR");
exit (EXIT_FAILURE);
}
break;
default:
message = "This is the parent";
n = Np;
exit_code = 0;
break;
}
//Print the message for the process using their values
for(; n > 0; n--) {
printf("(Task4.c)\tpid=%d ", pid);
puts(message);
switch(pid)
{
case 0:
sleep(Tc);
break;
default:
sleep(Tp);
break;
}
}
printf("\n\n");
exit(exit_code);
}
New Program Being Called By Child Process:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int arg2, char *argv2[]) {
if(arg2 < 3) {
printf("\n\t(child.c) Please provide the right arguments\n\n");
exit(EXIT_FAILURE);
}
int Nc2 = atoi(argv2[0]);
int Tc2 = atoi(argv2[1]);
int Np2 = 5;
int Tp2 = 1;
int n2, exit_code2;
//Here I was expected to get 0 as the pid...
pid_t pid2 = getpid();
char *message2;
printf("(child.c)\tchild program starting\n\n");
printf("(child.c)\tpid=%d \n\n", pid2);
switch(pid2)
{
case -1:
perror("(child.c) fork failed");
exit(1);
case 0:
message2 = argv2[2];
n2 = Nc2;
exit_code2 = 37;
break;
default:
message2 = "(child.c)\tThis is the parent";
n2 = Np2;
exit_code2 = 0;
break;
}
for(; n2 > 0; n2--) {
printf("(child.c)\tpid=%d ", pid2);
puts(message2);
switch(pid2)
{
case 0:
sleep(Tc2);
break;
default:
sleep(Tp2);
break;
}
}
exit(37);
}
Example Output:
Upvotes: 0
Views: 1833
Reputation: 137
I think you are confusing the meaning of the return value of fork(). It actually never returns the pid of the running process, but either the pid of the freshly spawned child (from the parent's perspective) or 0, which is not a valid pid but an indicator to identify the child. That return value is just a way to distinguish the two execution threads and for the parent to keep track which children have been spawned.
Upvotes: 3