继续从同一个父进程创建多个子进程

Keep creating multiple child processes from the same parent

我正在尝试使用单独的进程来计算当前目录中每个二进制文件的校验和以提高性能。但是,由于某些原因,我的输出总是出乎意料。

我将如何为每个文件创建一个单独的进程?我应该在 while(pids[i] != -1) 内完成整个分叉过程吗?

file_cnt = number of .bin files in the current dir

pid_t pids[file_cnt];

for(i = 0; i < file_cnt; i++) 
{
    if((pids[i]=fork()) < 0)
    {
        printf("Error forking");
        return 0;
    }
    else if(pids[i]==0)
    {
        printf("Entering child \n");
        printf("%s ", filenames[i]);

        //reading file
        handle = open( filenames[i], O_RDONLY );

        //allocating memory
        buffer = malloc( BUFFER_SIZE );

        checksum = 0;

        do
        {
            //calculating checksum
        } while( length );

        printf( " -%d\n", checksum);
        printf("Exiting child \n");
    }
}

我的目录中有三个文件,我的输出结果为:

There are 3 files:
Entering child 
whateve2.bin  -10540
Exiting child 
Entering child 
Entering child 
whatever.bin  -8399
Exiting child 
whatever3.bin  -34871
Exiting child 
Entering child 
whatever.bin  -8399
Exiting child 
vab@Vaibhav:~/CS330$ Entering child 
whatever3.bin  -34871
Exiting child 
Entering child 
whatever3.bin  -34871
Exiting child 
Entering child 
whatever3.bin  -34871
Exiting child

您没有在每个 child 的 else 块末尾调用 exit()。因此,child 将跳回 for 循环并执行下一次迭代,再次调用 fork()。如果有3个文件,parent会分叉3次,文件1的child会分叉2次,文件2的child会分叉1次。

在调用 printf("Exiting child \n"); 之后,您需要立即调用 exit(0),以便 child 进程退出。

针对您的评论,您调用 fork() 并检查 return 值不 < 0 确保创建了 child 进程,并检查 return 值为 0 确保 child 进程是 运行.

记住,如果成功,fork() return 会执行两次:一次是 parent 和 child 的 pid,一次是 child 与 0.

正如其他人所提到的,您没有 exit()else 块的末尾。

但是我想提出改进建议:由于您正在尝试实施并行处理以提高快速任务的性能,那么使用线程而不是 fork() 整个进程怎么样?

这是一个代码示例,说明了您可以做什么:

// adapted from https://computing.llnl.gov/tutorials/pthreads/
// compile with: gcc calc_checksum.c -o calc_checksum -lpthread

#include <pthread.h>
#include <stdio.h>

void* calc_checksum(void* pFileNameIdx)
{
    const int fileNameIdx = (int)pFileNameIdx;
    printf("Entering child \n");
    // filenames should be a global variable somewhere
    // or, better, just pass "&filenames[fileNameIdx]" instead of pFileNameIdx
    printf("%s ", filenames[fileNameIdx]);

    // reading file
    handle = open(filenames[fileNameIdx], O_RDONLY);

    // allocating memory
    buffer = malloc(BUFFER_SIZE);

    int checksum = 0;

    do
    {
        // calculating checksum
    } while(length);

    printf( " -%d\n", checksum);
    printf("Exiting child \n");

    free(buffer);  // !! don't forget to free() the resources that you don't need anymore

    // exit the thread
    pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
    // initialization code ...
    file_cnt = number of .bin files in the current dir

    pthread_t threads[file_cnt];
    int retCode;

    for(i = 0; i < file_cnt; i++) 
    {
        retCode = pthread_create(&threads[i], NULL, calc_checksum, (void*)i);
        if (retCode){
            printf("ERROR; return code from pthread_create() is %d\n", retCode);
            exit(-1);
        }
    }

    pthread_exit(NULL);
}

NB:无论使用何种方法(fork() 或 pthreads):不要忘记 free() 您使用 [=16] 保留的内存=].