fork的例子

//以下是下列代码的头文件
/*
 * forks.c - Examples of Unix process control
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h> 
#include <signal.h> 

(零)

/*
 * fork0 - The simplest fork example
 * Call once, return twice
 * Creates child that is identical to parent
 * Returns 0 to child process
 * Returns child PID to parent process
 */
void fork0() 
{
    if (fork() == 0) {
 printf("Hello from child\n");
    }
    else {
 printf("Hello from parent\n");
    }
}

在这里插入图片描述使用fork创建一个子进程,子进程打印出(“Hello from child”);
父进程打印出(“Hello from parent”);

(一)

/* 
 * fork1 - Simple fork example 
 * Parent and child both run same code
 * Child starts with identical private state
 */
 void fork1()
 {
       int x = 1;
       pid_t pid = fork();
       if(pid==0){
               printf("Child has x = %d\n",++x);
         }
         else{
                   printf("Parent has x = %d\n",--x);
            }
            printf("Bye from process %d with x = %d\n",getpid(),x);
     }

在这里插入图片描述使用getpid可以得到创建子进程的ID号
父进程和子进程是独立运行的

(二)

/*
 * fork2 - Two consecutive forks
 * Both parent and child can continue forking
 * Ordering undetermined
 */
 void fork2()
 {
       printf("L0\n");
       fork();
       printf("L1\n");
       fork();
       printf("Bye\n");
   }

在这里插入图片描述
在这里插入图片描述

(三)

/*
 * fork3 - Three consective forks
 * Parent and child can continue forking
 */
 void fork3()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("L2\n");    
    fork();
    printf("Bye\n");
}

在这里插入图片描述
在这里插入图片描述

(四)

/* 
 * fork4 - Nested forks in parents
 */
 void fork4()
{
    printf("L0\n");
    if (fork() != 0) {
 printf("L1\n");    
 if (fork() != 0) {
     printf("L2\n");
 }
    }
    printf("Bye\n");
}

在这里插入图片描述
在这里插入图片描述

(五)

/*
 * fork5 - Nested forks in children
 */
void  fork5()
{
    printf("L0\n");
    if(fork()==0){
           printf("L1\n");
           if(fork()==0){
                printf("L2\n");
            }
         }
         printf("Bye\n");
  }
``
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191129175336666.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191129180351581.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3oxOTExNzI1MTQ1,size_16,color_FFFFFF,t_70)


**(六)**

void cleanup(void) {
printf(“Cleaning up\n”);
}
/*

  • fork6 - Exit system call terminates process
  • call once, return never
    */
    void fork6()
    {
    atexit(cleanup);
    fork();
    exit(0);
    }
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191129180955952.png)

**(七)**

/*

  • fork7 - Demonstration of zombies.
  • Run in background and then perform ps
    /
    void fork7()
    {
    if (fork() == 0) {
    /
    Child /
    printf(“Terminating Child, PID = %d\n”, getpid());
    exit(0);
    } else {
    printf(“Running Parent, PID = %d\n”, getpid());
    while (1)
    ; /
    Infinite loop */
    }
    }
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191129181226323.png)
子进程正常退出,父进程进入死循环,所以要使用Ctrl+C终止进程

**(八)**

/*

  • fork8 - Demonstration of nonterminating child.
  • Child still running even though parent terminated
  • Must kill explicitly
    /
    void fork8()
    {
    if (fork() == 0) {
    /
    Child /
    printf(“Running Child, PID = %d\n”,
    getpid());
    while (1)
    ; /
    Infinite loop */
    } else {
    printf(“Terminating Parent, PID = %d\n”,
    getpid());
    exit(0);
    }
    }
    ``
    在这里插入图片描述子进程进入死循环,父进程正常退出,回收子进程。

(九)

/*
 * fork9 - synchronizing with and reaping children (wait)
 */
 void fork9()
 {
      int child_status;
      if(fork()==0){
            printf("HC:hello from child\n");
            exit(0);
         }else{
                   printf("HP:hello from parent\n");
                   wait(&child_status);
                   printf("CT:child has terminated\n");
           }
           printf("Bye\n");
    }

在这里插入图片描述
wait表示等待子进程结束以后执行wait后续的代码,所以最后打印出CT:child has terminated

(十)

#define N 5
/* 
 * fork10 - Synchronizing with multiple children (wait)
 * Reaps children in arbitrary order
 * WIFEXITED and WEXITSTATUS to get info about terminated children
 */
 void fork10()
 {
       pid_t pid[N];
       int i,child_status;
       for(i=0;i<N;i++)
               if((pid[i]=fork())==0){
                     exit(100+i);
                     }
          for(i=0;i<N;i++){
                    pid_t wpid=wait(&child_status);
                    if(WIFEXITED(child_status));
                          printf("Child %d terminated with exit status %d\n",wpid,WEXITSTATUS(child_status));
                       else
                            printf("Child %d terminate abnormally\n",wpid);
                }
      }

在这里插入图片描述
创建了5个子进程,并且将退出状态码返回给父进程。

(十一)

/*
*fork11
*Reaps children in reverse order
*/
void fork11()
{
      pid_t   pid[N];
      int i;
      int child_status;
      for(i=0;i<N;i++)
                if((pid[i]=fork())==0)
                      exit(100+i);
         for(i=N-1;i>=0;i--){
               pid_t  wpid=waitpid(pid[i],&child_status,0);
               if(WIFEXITED(child_status))
                     printf("Child %d terminated with exit status %d\n",wpid,WEXITSTATUS(child_status));
                     else
                           printf("Child %d terminate abnormally\n",wpid);
             }
    }

在这里插入图片描述相比于fork10,这里将输出进行排序输出

(十二)

/*
 * fork12 - Sending signals with the kill() function
 */
 void fork12()
 {
      pid_t   pid[N];
      int i;
      int child_status;
      for(i=0;i<N;i++)
            if((pid[i]=fork())==0){
                 while(1);
              }
    for(i=0;i<N;i++){
           printf("Killing process %d \n",pid[i]);
           kill(pid[i],SIGINT);
     }
     for(i=0;i<N;i++){
            pid_t  wpid=wait(&child_status);
            if(WIFEXITED(child_status))
                  printf("Child %d terminated with exit status %d\n",wpid,WEXITSTATUS(child_status));
              else
                  printf("Child %d terminated abnormally\n",wpid);
         }
     }




`
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191129231017804.png)
由于子进程进入了死循环,所以使用kill将子进程都杀死,因为子进程没有创建成功,所以执行了(Child %d terminated abnormally")


**(十三)**

/*
*int_handler -SIGINT handler
/
void int_handler(int sig)
{
printf(“Process %d received signal %d\n”,getpid(),sig);
exit(0);
/

*fork13 -Simple signal handler example
*/
void fork13()
{
pid_t pid[N];
int i;
int child_status;
signal(SIGINT,int_handler);
for(i=0;i<N;i++)
if((pid[i]=fork())==0){
while(1);
}
for(i=0;i<N;i++){
printf(“Killing process %d\n”,pid[i]);
kill(pid[i],SIGINT);
}
for(i=0;i<N;i++){
pid_t wpid=wait(&child_status);
if(WIFEXITED(child_status))
printf(“Child %d terminated with exit status %d\n”,wpid,WEXITSTATUS(child_status));
else
printf(“Child %d terminated abnormally\n”,wpid);
}
}

``
在这里插入图片描述
fork13相比与fork12将处理函数转给自定义的函数进行处理。

(十四)

/*
 * child_handler - SIGCHLD handler that reaps one terminated child
 */
 int ccount = 0;
 void child_handler(int sig)
 {
        int child_status;
        pid_t pid = wait(&child_status);
        ccount--;
         printf("Received SIGCHLD signal %d for process %d\n", sig, pid); 
         fflush(stdout);
  }
 void fork14()
 {
       pid_t pid[N];
       int i;
       ccount = N;
        signal(SIGCHLD, child_handler);
          for (i = 0; i < N; i++) {
                if ((pid[i] = fork()) == 0) {
                      sleep(1);
                       exit(0); 
                   }
            }
            while(ccount>0);
    }

在这里插入图片描述

(十五)

/*
 * child_handler2 - SIGCHLD handler that reaps all terminated children
 */
 void child_handler2(int sig)
 {
       int child_status;
       pid_t pid;
        while ((pid = wait(&child_status)) > 0) {
                    ccount--;
                    printf("Received signal %d from process %d\n", sig, pid); 
                    fflush(stdout); 
               }
}
/*
 * fork15 - Using a handler that reaps multiple children
 */
 void fork15()
 {
        pid_t pid[N];
        int i;
        ccount = N;
        signal(SIGCHLD, child_handler2);
        for (i = 0; i < N; i++)
                   if ((pid[i] = fork()) == 0) {
                         sleep(1);
                         exit(0);
                     }
           while(ccount>0){
                pause();
           }
    }
                   

在这里插入图片描述这里使用pause将暂停,先让子进程的5个循环做完。

(十六)

/* 
 * fork16 - Demonstration of using /bin/kill program 
 */
 void fork16() 
 {
        if (fork() == 0) {
             printf("Child1: pid=%d pgrp=%d\n",
                      getpid(), getpgrp());
               if (fork() == 0)
                       printf("Child2: pid=%d pgrp=%d\n",
                                  getpid(), getpgrp());
                  while(1);
          }
    }

在这里插入图片描述

(十七)

/* 
 * Demonstration of using ctrl-c and ctrl-z 
 */
 
void fork17() 
{
           if (fork() == 0) {
                   printf("Child: pid=%d pgrp=%d\n",
                        getpid(), getpgrp());
    } else {
                 printf("Parent: pid=%d pgrp=%d\n",
        getpid(), getpgrp());
  }
    while(1);
} 

在这里插入图片描述
进入死循环时,可以使用Ctrl+c进行终止,使用Ctrl+z进行挂起

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我理解了你的问题。这里是一个用Java的Fork/Join框架实现的带返回值的例子: ``` import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask; public class ForkJoinTaskDemo { public static void main(String[] args) { ForkJoinPool forkJoinPool = new ForkJoinPool(); // 定义一个带有返回值的ForkJoinTask FibonacciTask fibonacciTask = new FibonacciTask(10); // 提交ForkJoinTask,获取结果 int result = forkJoinPool.invoke(fibonacciTask); System.out.println("result: " + result); } private static class FibonacciTask extends RecursiveTask<Integer> { private int n; public FibonacciTask(int n) { this.n = n; } @Override protected Integer compute() { if (n <= 1) { return n; } // 将 n 分成两部分 FibonacciTask leftFibonacciTask = new FibonacciTask(n - 1); leftFibonacciTask.fork(); // 异步执行 FibonacciTask rightFibonacciTask = new FibonacciTask(n - 2); rightFibonacciTask.fork(); // 异步执行 // 结果合并 return leftFibonacciTask.join() + rightFibonacciTask.join(); } } } ``` 这个例子中,我们定义了一个FibonacciTask类并继承自RecursiveTask类,实现了compute()方法。compute()方法中判断n的值是否小于等于1,如果是就直接返回n的值,否则就将n分成左右两部分,分别用两个新的FibonacciTask异步执行,并使用join()方法将它们的结果合并,最后返回结果。在main()方法中,我们创建了一个带有返回值的FibonacciTask,提交给ForkJoinPool执行,最终返回结果并输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值