我正在创建多个子进程并使用消息队列传递数据。我已经删除了我的代码的大部分细节,因为它有点太大了,无法在线发布作业,我已经缩小了与我如何创建和处理子进程有关的错误。
该计划如何运作的基础知识:
从标准输入读取
分叉子进程(类型1)来处理数据
通过消息队列
他们填充数据并通过消息队列传递给print_queue函数
type2进程一直等到它们的消息队列为空(由print_queue读取),然后才会退出exit(0)
我删除的程序中的所有内容都有效并经过测试。消息传递正在工作,从stdin读取和计算的东西正在工作。当我打印数据时出现问题。结果取决于数据集的大小以及我如何获取数据。如果我打印到终端,一切都很好。如果我将输出重定向到文件,我会得到以下结果(请记住我在主页顶部打印“启动程序”):
** valid data
.
. x100k more lines of valid data
.
.
** valid data
** vali Starting Program
Starting Program
请注意,程序最终会重新启动两次。对于较小的数据集,该程序运行良好,甚至在打印到屏幕时也可以运行非常大的数据集。另一个更奇怪的错误是当我注释掉“启动程序”printf时。由于某种原因,总是会导致程序出现段错误。
以下是源代码的精简版本:
/*
fork a process, child process type 1
*/
void Process1(){
switch(fork()){
case 0:
// Read some stuff from stdin
// Pass data to other child processes through msgsnd
// wait until message queue is empty
// close message queue, to tell child processes (type 2)
// that there is no more data
break;
case -1:
perror("error fork\n");
break;
default:
break;
}
}
/*
fork a process of type 2
*/
void process2( ){
switch(fork()){
case 0:
// Create a child process type-2
// Do stuff with this data
// send data back to print_queues function
// to do stuff with and display the results
// exit to get out and avoid going back to main
exit(0);
case -1:
perror("error fork\n");
break;
default:
break;
}
}
void print_queues(){
// This just prints data sent to it from process2 message queues
}
int main(int argc, char *argv[]){
// get a value num from argv, this is the
// number of instances of process2 that we will create
while ((c = getopt (argc, argv, "n:")) != -1)
{
switch (c)
{
case 'n':
if(atoi(optarg) < 0 || atoi(optarg) > 50){
printf("invalid No \n");
num = 1;
}
else{
num = atoi(optarg);
}
// create memory for key and queue arrays
Keys = malloc(sizeof(key_t)*num);
queues = malloc(sizeof(int)*num);
fflush(stdout);
break;
default:
break;
}
}
printf("Starting program\n");
// create num version of child2
for(i = 0; i < num; i++){
process2();
}
// create process1
process1();
// wait for process 1 to finish
wait(NULL);
// print the output from the message queues
print_queues();
// wait for num versions of process2 to finish
for(i = 0; i < num; i++){
wait(NULL);
}
return 0;
}