我正在尝试使用单独的进程计算当前目录中每个二进制文件的校验和,以提高性能。但是,出于某种原因,我的输出始终是意外的。
我如何为每个文件创建单独的进程?我应该在 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
答案 0 :(得分:2)
您并未在每个孩子的exit()
区块末尾为else
致电。因此,孩子将跳回for
循环并执行下一次迭代,再次调用fork()
。如果有3个文件,父文件将分叉3次,文件1的子文件将分叉2次,文件2的子文件将分叉1次。
在致电printf("Exiting child \n");
之后,您需要致电exit(0)
,以便子流程退出。
解决你的评论,你调用fork()
并检查返回值不是&lt; { 0确保创建子进程,并检查返回值是否为0,确保它是正在运行的子进程。
请记住fork()
如果成功则返回两次:一次是带有孩子的pid的父级,一次是带给0的子级。
答案 1 :(得分:1)
正如其他人所说,你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()
使用malloc()
保留的内存。