Fork()子链

时间:2016-10-19 15:46:18

标签: c fork wait

我有以下代码,它使用fork()

创建定义数量的子线程
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

#define NUM_THREADS     4

int main()
{
        int i;
        pid_t pid;
        for(i = 0; i < NUM_THREADS; i++){ //Do this equal to the number of threads
            pid = fork();//Use this to avoid multiple forking

            if(pid == 0){ //If it's a child process
                    printf("Hello World! Greetings from PID: %ld! :D\n", (long)getpid()); //getpid returns the pid of the process
                    exit(0); //Exit the process
            }else if(pid == -1){
                    printf("Oh no! Could not fork! :( Exiting!\n");
                    return 0;
            }
    }
    int status;
    for(i = 0; i < NUM_THREADS; i++){
            wait(&status);//wait until all the children processes have finished.
    }
    printf("All done! I am the parent process! My PID is: %ld if you were curious! \n", (long)getpid());

    return 0;

}

这是作为一个例子提供给我们的。 它的输出如下:

  

Hello World!来自PID的问候:118358! :d
  你好,世界!来自PID的问候:118359! :d
  你好,世界!来自PID的问候:118360! :d
  你好,世界!来自PID的问候:118362! :d

我想要做的是,让父进程创建一个子进程,而不是让父进程有多个子进程,以创建一个子进程,依此类推定义的线程数。我怎么能这样做?

3 个答案:

答案 0 :(得分:3)

您的示例代码使用fork()的返回值来区分父级和子级。它继续在父级中迭代(假设fork()没有报告错误),并且exit()在子级中没有迭代(在发出一些输出之后)。这是完全常规的。

你打算做的事情并没有太大的不同;你所描述的主要是交换父母和孩子的角色。实际上,你的工作比较简单,因为每个父母只需要wait()一个孩子。它可以在循环内部或外部执行此操作,前提是仅在最后一个子wait() s时,它应该预期该调用指示由于该子级没有自己的子级而导致的错误。但是,如果父级不是来自循环内部的exit()return,那么它确实需要突破而不是进一步迭代。

答案 1 :(得分:2)

此任务与将迭代解决方案转换为递归解决方案相同。第一步是删除for循环。然后修改子代码以便每个子代:

  1. 打印其消息
  2. 更新计数变量,如果计数小于最大值
  3. 分叉一个新孩子
  4. 等待其孩子
  5. 关键是每个孩子都会获得其父变量的副本,因此如果孩子更新计数变量,然后分叉,新孩子将看到更新的计数。

答案 2 :(得分:1)

首先,术语&#34;线程&#34;你在这种情况下使用是不合适的。 分叉意味着&#34;创建过程&#34;不是&#34;线程&#34;。

您可以使用递归解决方案,但您必须记住创建进程的每个进程都应该等待返回状态以避免Zombie Process。如果不在进程之间使用任何共享变量,则可以使用单个变量计数器,该计数器在每次分叉时都会递增。但是一旦计数器变量达到最大值,最小的&#34;最年轻的&#34;进程,我的意思是创建的最后一个进程应该退出,并且一个接一个的进程将退出。

这是一个很好的简单代码:

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

#define NUM_PROCESS 5

int counter = 0;

void child_func() 
{
    pid_t pid;

    if (counter < NUM_PROCESS) {

        counter++;

        pid = fork();

        if (pid < 0) {

            printf("fork failed counter = %d\n", counter);

        }
        else if (pid == 0) {

            printf("Hello world ! Greetings from pid %ld\n", (long)getpid());

            if (counter == NUM_PROCESS) {
                exit(0);
            }
            else {
                child_func();
            }
        }
        else {

            long var  = pid;

            wait(&pid);

            printf("My pid is %ld and i am the parent of %ld child, i exit\n", (long)getpid(), var);

            exit(0);
        }   
    }
}

int main(void) 
{

    pid_t pid;

    pid = fork();

    if (pid < 0) {

        printf("Fork failed %d\n", counter);

        return -1;
    }

    if (pid == 0) {

        child_func();
    }
    else {

        wait(&pid);
    }

    return 0;
}

See output