[英]execv on a child process is keeping its parents process id in the new program instead of zero
Program Description: 程序说明:
I am working on a program to help teach me about processes in C and Linux. 我正在开发一个程序,以帮助我了解C和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. 该程序使用
fork
创建一个子进程,然后父级和子级都打印出一定时间的消息,并相应地说出Parent Process
, Child Process
。 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. 为了使事情变得更加有趣,子进程使用
execv
调用另一个打印其消息的程序。
From what I've read on execv
a new process is not started; 根据我对
execv
的了解,尚未启动一个新进程。 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.
因此,当子进程启动新程序时,该新程序中的进程ID应与子进程ID相同(零)。
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). 当我在调用
execv
之前打印出孩子的进程ID时,它为零(按预期),但是一旦我进入新程序,我就打印出进程ID,它是父进程ID(但应该是孩子的ID)。 。
Could anyone please explain why the new program does not have zero as the process id? 谁能解释为什么新程序的进程ID不为零?
Arguments: 参数:
Argv[1]
= Number of times the message prints for the child process Argv[1]
=消息为子进程打印的次数 Argv[2]
= Number of times the message prints for the parent process Argv[2]
=消息为父进程打印的次数 Argv[3]
= Number of seconds waited after a message for the child process Argv[3]
=子进程消息后等待的秒数 Argv[4]
= Number of seconds waited after a message for the parent process Argv[4]
=父进程消息后等待的秒数 Argv[5]
= Message sent to the new program the child process starts (child processes message to be printed). Argv[5]
=消息发送到子进程开始的新程序(要打印的子进程消息)。 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: 示例输出:
I think you are confusing the meaning of the return value of fork(). 我认为您在混淆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.
实际上,它永远不会返回正在运行的进程的pid,而是返回新生成的子进程的pid(从父级的角度来看)或0,这不是有效的pid,而是标识该子进程的指示器。 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.
该返回值仅是区分两个执行线程的一种方法,并且父级可以跟踪生成了哪些子级。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.