首页 > 解决方案 > 使用 fork (process) 而不是 pthread 来实现相同的

问题描述

我通过创建并行线程实现了以下代码的并发性。但是,我应该如何使用 fork() 创建子进程并完成与下面的 main() 相同的工作?我想避免创建任何线程。

struct function_args
    {
        pthread_t thread;
        char *command;
    };
    
    int main()
    {
        while (1)
            {
                if (mode == 1)
                    printf("$> ");
    
                if ((nread = getline(&line, &linecap, in)) > 0)
                {
                    char *command;
                    int commands_num = 0;
                    struct function_args args[BUFF_SIZE];
    
                    // remove newline character
                    if (line[nread - 1] == '\n')
                        line[nread - 1] = '\0';
    
                    char *temp = line;
    
                    while ((command = strsep(&temp, "&")) != NULL)
                        if (command[0] != '\0')
                        {
                            args[commands_num++].command = strdup(command);
                            if (commands_num >= BUFF_SIZE)
                                break;
                        }
    
                    for (size_t i = 0; i < commands_num; i++)
                        if (pthread_create(&args[i].thread, NULL, &parseInput, &args[i]) != 0)
                            printError();
    
                    for (size_t i = 0; i < commands_num; i++)
                    {
                        if (pthread_join(args[i].thread, NULL) != 0)
                            printError();
                        if (args[i].command != NULL)
                            free(args[i].command);
                    }
                }
                else if (feof(in) != 0)
                {
                    atexit(clean);
                    exit(EXIT_SUCCESS);    // EOF
                }
            }
    
            return 0;
    }

我知道pid = fork()返回的 processid 为 0 为孩子和 > 0 为父母。但是,在下面我处理多个的 for 循环中,我argv不确定如何翻译我的 main() 来做到这一点。

标签: cpointersprocesspthreadsfork

解决方案


这真的取决于你在做什么。一般来说,您可以执行以下操作:

for (size_t i = 0; i < commands_num; i++)
{
    pid_t pid = fork();
    if (pid == 0)
    {
        parseInput(&args[i]);
        exit(0);
    }
    else if (pid == -1)
        printError();
    else
        args[i].thread = pid;
}

子进程独立于父进程工作并继续完成他们的任务,因此可能不需要执行与pthread_join()此处等效的操作,在这种情况下waitpid(),除非父进程必须等待他们的产品对其进行处理。

说到这一点,一旦进程被分叉,它们就不再共享相同的内存空间,因此在子进程和父进程之间传输信息本身可能是一个挑战。如果你只是打印东西,stdout你就准备好了,否则你必须弄清楚让父母和孩子交流的管道。

使用系统本机线程(或特别是 pthreads)的另一种替代方法是使用一些绿色线程库,例如libdill,理论上它即使在不支持本机多线程的系统中也可以启用多线程。


推荐阅读