简体   繁体   English

子进程上的execv将其父进程ID保留在新程序中,而不是零

[英]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 ProcessChild 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: 示例输出:

  • With arguments as (5 3 1 1 "Hello From Child") 参数为(5 3 1 1“ Hello From Child”)

在此处输入图片说明

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM