【问题标题】:How to terminate only the child process?如何仅终止子进程?
【发布时间】:2017-09-06 14:09:06
【问题描述】:

我想用pidburst time 打印一系列进程。为此,我使用fork() 生成pid,然后使用getpid() 得到它pid。但是,由于 fork 创建了一个与父进程隔离运行的子进程,因此我没有得到预期的行为。程序应该做的是为给定的number_of_process 生成进程,然后将pid 和randomburst time 值存储在特定的结构元素中。这是我的代码:-

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>

struct process{
    int pid;
    int bt;
};

int main()
{   
    int no_of_process,i,new_process;
    printf("Enter the number of process\n");
    scanf("%d",&no_of_process);
    struct process p[no_of_process];
    for(i=0;i<no_of_process;i++){
        new_process=fork();
        p[i].pid = getpid();
        p[i].bt = rand()%10;
        //kill(getpid(),SIGKILL);
    }
    for(i=0;i<no_of_process;i++){
        printf("process %d and bt %d\n",p[i].pid,p[i].bt);
    }
    return 0;
}

我试图杀死子进程,但这会停止整个程序。 进程数的输出 = 2

process 6373 and bt 3
process 6373 and bt 6
process 6374 and bt 3                                                           
process 6376 and bt 6
process 6373 and bt 3
process 6375 and bt 6
process 6374 and bt 3
process 6374 and bt 6

预计应该只有 2 个具有 pid 和 bt(突发时间)的进程。

  • 如何在存储 pid 和 bt(burst time) 后立即杀死子进程,否则无法完成?

【问题讨论】:

  • 你的子进程和父进程做同样的事情,所以你会得到你不想要的行为。测试new_process 中的值,如果它为零(子)或不为零(父),则执行不同的操作。注意getpid()返回当前进程的PID。
  • 是的,我也想过同样的事情。由于内存是共享的,这就是为什么该结构为每个进程存储 5 个元素,然后每个进程运行循环 5 次。但是我怎样才能得到这样的PID而不面临这个问题并且仍然只有给定的号码。进程,这样一旦创建了进程并且我得到了它的 pid,我就可以完成它的执行。有没有办法做到这一点?但是,在这种情况下,我必须弄清楚如何存储 pid,因为子进程和父进程都使用不同的结构。这可能吗?
  • @ZameerHaque 内存不在进程之间共享——它们是完全独立的。
  • @ChrisTurner 谢谢。这就是我真正想说的。那么我如何让两个进程共享相同的结构,以便只创建 2 个进程并将其存储在 no_of_process = 2 的结构中。
  • @ZameerHaque 您根据下面的许多答案检查fork 的返回值,并在父进程中将 PID 存储在结构中。

标签: c fork


【解决方案1】:

您根本没有正确使用fork。当您调用它时,子进程继续执行与父进程相同的代码,但获得不同的返回值 (0) 以表明它是子进程。因此,目前在您的代码中,子进程都在生成自己的子进程。

使用fork 的通常方式是做类似的事情

new_process=fork();
if(new_process==0)
  {
  // I am the child
  }
else if(new_process==-1)
  {
  // Something bad happened
  }
else
  {
  // I am the parent
  }

【讨论】:

  • 是的。尝试了上面的答案stackoverflow.com/a/46077676/5143144,但是 pid 现在保持不变并且根本没有改变。该进程应该有唯一的 pid。
  • new_process 的值将包含每个孩子的唯一 PID - 您将其放入您的结构中
【解决方案2】:

您需要注意fork 的返回值。对您的代码进行的这个小修改可能会满足您的需求。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>

struct process{
    int pid;
    int bt;
};

int main()
{   
    int no_of_process,i,new_process;
    printf("Enter the number of process\n");
    scanf("%d",&no_of_process);
    struct process p[no_of_process];
    for(i=0;i<no_of_process;i++){
        new_process=fork();
        if (new_process == 0) {
            // This is a child process. Just spin until killed.
            while(true);
        }
        p[i].pid = new_process;
        p[i].bt = rand()%10;
        kill(new_process,SIGKILL);
    }
    for(i=0;i<no_of_process;i++){
        printf("process %d and bt %d\n",p[i].pid,p[i].bt);
    }
    return 0;
}

【讨论】:

  • 在这种情况下,所有进程的 pid 保持不变。为什么 ?我想自从最后一个过程已经完成执行了?如何每次生成唯一的 pid。
  • 运行这个确切的代码我每次都会得到一个不同的 pid。您是否确保将行从 p[i].pid = getpid(); 更新为 p[i].pid = new_process;
  • 使用忙碌的等待是有效的,但调用pause() 通常会更好。它永远不会正常返回;它仅在处理完信号后返回(因此使用 SIGKILL,它永远不会返回),但在暂停时它不会运行并使用任何 CPU 资源。
  • 哦,我明白了。谢谢。但是为什么它与 getpid() 不同。 getpid 应该给出当前进程 id 吗?哦。由于进程已经完成执行,所以我每次使用 getpid() 时都使用父进程 ID?
  • 在这种情况下,子进程从不调用getpid();,只有父进程调用它,所以每次都会返回相同的答案。 fork() 的返回值是子进程的 pid 与父进程通信的方式。
【解决方案3】:

在您的代码中,new_process 要么是 0(所以它是孩子)要么是孩子的 pid - 无需调用 getpid(忽略 -1 表示失败)

所以,在父(0返回值)调用forkno_of_processes

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-05
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多