如何从单个Parent创建两个进程

时间:2011-07-01 00:26:41

标签: c ipc fork parent-child

我知道我将需要使用fork(),但这只会创建一个子进程。我是否只是在子进程中再次调用fork?此外,我需要他们通过信号或管道进行通信,这更容易实现,我需要知道做什么(功能等)。

8 个答案:

答案 0 :(得分:11)

要创建第二个进程,请再次调用fork() - 在父级或子级内(但不能同时调用两者!)。您选择哪个取决于您是希望此进程是原始父进程的子进程还是第一个子进程的子进程(通常它是原始父进程的子进程)。

通过管道进行通信比使用信号更简单,更可靠。 pipe()close()read()write()select()是此处的主要功能。


例如,要让父级创建两个子进程,您可以执行以下操作:

pid_t child_a, child_b;

child_a = fork();

if (child_a == 0) {
    /* Child A code */
} else {
    child_b = fork();

    if (child_b == 0) {
        /* Child B code */
    } else {
        /* Parent Code */
    }
}

答案 1 :(得分:3)

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

void main(){
  int pi_d ;
  int pid ;
  pi_d = fork();
  if(pi_d == 0){
    printf("Child Process B:\npid :%d\nppid:%d\n",getpid(),getppid());
  }
  if(pi_d > 0){
    pid = fork();
    if(pid > 0){
      printf("\nParent Process:\npid:%d\nppid :%d\n",getpid(),getppid());
    }
    else if(pid == 0){
      printf("Child Process A:\npid :%d\nppid:%d\n",getpid(),getppid());
    }
  }
}

输出:

Parent Process:
pid:3648
ppid :2379
Child Process B:
pid :3649
ppid:3648
Child Process A:
pid :3650
ppid:3648

答案 2 :(得分:2)

使用&&运算符的另一个精美代码:

pid_t c1_pid, c2_pid;

(c1_pid = fork()) && (c2_pid = fork()); // Creates two children

if (c1_pid == 0) {
    /* Child 1 code goes here */
} else if (c2_pid == 0) {
    /* Child 2 code goes here */
} else {
    /* Parent code goes here */
}

答案 3 :(得分:1)

您可以将fork放在循环中,并根据需要生成任意数量的子进程。 我最近在一个项目上做到了这一点。

for(nSon=0; nSon < nSonsAsked; nSon++) {
  Log_Print("Setup son #%.2u ", nSon+1);

  if((pid = fork()) == 0) {
    /* Do child stuff init, like connect the pipes, close shared handles */

    return iTMInChild(...);     /* A specific function of the child work */
  /* The life of the child should not go beyond that point, i.e. the loop is over 
     or else the child will spawn even more processes. */ 
  }
  else if(pid > 0) {
    /* Father process stuff. Here I initialise an array with the pid of the forked */
    /* processes, this way I can index with the number of processes.*/
    pid[nSon] = pid;
  }
  else
    return Err_Print(ERR_FORK_FAILED, "fork failed. errno=%d \"%s\"\n", errno, strerror(errno));
}

Log_Print()和Err_Print()是内部函数,但非常明显,所以我让它们就像它们一样。

必须解释变量的一个方面。 nSonnSonAsked应该声明为全局变量而不是堆栈变量。这样,它们的值在分叉过程中持续存在。这意味着nSon变量在每个子节点中具有不同的值。这使得它具有比ownpid()数字更简单的编号方案。

为了完全正确,有很多细节要做对。您必须在父进程中设置信号处理程序以检测子进程的死亡,同样反过来(仅在Linux上可用,其他Unix(至少Solaris)不支持父死亡信号)。 你必须要知道父进程中的打开文件描述符也将在fork之后在子进程中打开,它将是相同的。如果你不了解它会导致很多并发问题(解决方案是在正确的位置使用dup()close())。

答案 4 :(得分:0)

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
    system ("clear");
    int i ;
    pid_t childa,childb,childa1,childa2,childb1,childb2;
    printf("\n \t \t I am the parent process with ID %d \n",getpid());
    childa=fork();
    if (childa == 0 )
    {
        printf("\nI am a child A with PID %d and my parent ID is %d\n",getpid(),getppid());
    }
    else
    {
        childb = fork();
        if (childb == 0)
        {
            printf("\nI am Child B with ID %d and my parent ID is %d\n",getpid(),getppid());
        }
        else
        {
            sleep(1);
        }
    }
}

答案 5 :(得分:0)

在这个例子中

他们只是随机休息几秒钟。它还包含所有 pid ,因此我们可以发送 SIGNAL 进行通信...

大多数#includes都是评论原因在我编译的地方,它们毫无用处。

 &lt;status&gt;success&lt;/status&gt;&lt;errorcode&gt;0&lt;/errorcode&gt;&lt;errormsg /&gt;&lt;guid&gt;d785f819-6fc1-1c68-8edf-bbb65cba5412&lt;/guid&gt;&lt;/paysecure&gt;

答案 6 :(得分:0)

只需做一点贡献,如果你想从同一个父母创建2个孩子,你可以使用下面的代码。其中一个父亲创建了2个子进程(懒惰和活动)。

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

int main (){
  pid_t lazy_child;

  lazy_child = fork();

  if(lazy_child == 0){ // This is the lazy child process.
    printf("LAZY CHILD:%d\n", getpid());
  }
  else if(lazy_child > 0){ // This is the father process.
    pid_t active_child = fork();

    if(active_child == 0){ // This is the active child process.
      printf("ACTIVE CHILD:%d\n", getpid());
    }
    else if(active_child > 0){ // This is the father process.
      printf("FATHER:%d\n", getpid());
    }
    else{ // Fork doesnt work.
      printf("fork error\n");
      exit(1);
    }
  }
  else{ // Fork doesnt work.
    printf("fork error\n");
    exit(1);
  }
  return 0;
}

如果运行此代码,则应获得类似的输出:

$ ./a.out 
FATHER:14501
ACTIVE CHILD:14503
LAZY CHILD:14502

答案 7 :(得分:0)

#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t AliceID, BobID;
double n=0;
int i1 =0;
/* fork a child process */
AliceID = fork();

if (AliceID < 0) { /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
else if (AliceID == 0) { /* child Alice code */
    for(int i=1; i<11; i++)
          {n = n+i;
           i1++; }
        double avg1 = n/i1;
       printf("From Alice: the average of 1,2, …, 10 is the-average-she-calculated");
       printf("  sum = %.2f and avg = %.2f \n",n, avg1); 
     }
   else  { 
          BobID = fork();
         if (BobID == 0) { /* Child Bob code */
          printf("From Bob: I am born to print this and then die.\n");

        } else {  /* Parent Code */
                  /* parent will wait for the child to complete */
            wait(NULL);
            printf("From parent: AliceID is %d \n",  AliceID);
            printf("From parent: Bob is %d \n",  BobID);
            printf("Parent ID %d \n", getpid());

         }
}
return 0;
}