【问题标题】:Keep creating multiple child processes from the same parent继续从同一个父进程创建多个子进程
【发布时间】:2015-10-11 21:03:27
【问题描述】:

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

如何为每个文件创建一个单独的进程?我应该在 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

【问题讨论】:

  • 您的代码打印出Exiting child,但不会退出子进程。
  • 如果没有被信号杀死,进程在到达main结尾或调用exit()时退出。
  • 始终检查 (!=NULL) malloc() 的返回值以确保操作成功。始终检查 (>=0) open() 的返回值以确保操作成功。
  • 每个孩子需要close()输入文件并将malloc的内存传递给free()并调用exit(0);
  • 校验和通常不是有符号值。所以它应该被声明为unsigned int checksum; 并且应该被打印为“%8X”。为什么 printf() 语句的格式说明符前面有一个“-”?

标签: c fork child-process


【解决方案1】:

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

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

针对您的评论,您调用fork() 并检查返回值不

请记住,如果成功,fork() 会返回两次:一次使用子进程的 pid 向父级返回,一次使用 0 向子级返回。

【讨论】:

  • 代码似乎完美无缺。虽然,我无法检查是否涉及不同的流程或者这是一个大流程。但是非常感谢您的帮助。
  • @Vab 您可以通过在代码的子部分打印getpid() 的值来验证是否正在使用不同的进程。另外,如果您觉得有用,请随时 accept this answer。
【解决方案2】:

正如其他人所说,您不是 exit()ing 在 else 块的末尾。

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

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

// 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);
}

注意:无论使用哪种方法(fork() 或 pthreads):不要忘记 free() 使用 malloc() 保留的内存。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-05-11
  • 2017-08-02
  • 2023-03-15
  • 2016-07-24
  • 2015-01-26
  • 1970-01-01
  • 2023-04-04
  • 2016-07-27
相关资源
最近更新 更多