C++ 使用exec对发送给子级的随机数进行排序

C++ 使用exec对发送给子级的随机数进行排序,c++,c,exec,C++,C,Exec,我试图做的是发送由父级生成的随机数,然后发送给子级,然后子级执行“sort-nr”,然后将排序后的数发送回父级。我发现这个问题已经被问到了,并且在这里得到了与我非常相似的回答:,我认为我做了它所说的一切来让它工作,但是我不能让排序真正发生。我甚至检查过它是否出错,但我什么也没得到 两个管道发送和接收相同的数字,但它们从未被分类。我错过了什么 int pipe1[2], pipe2[2]; pid_t childID; if (pipe(pipe1) < 0 || pipe(pipe2)

我试图做的是发送由父级生成的随机数,然后发送给子级,然后子级执行“sort-nr”,然后将排序后的数发送回父级。我发现这个问题已经被问到了,并且在这里得到了与我非常相似的回答:,我认为我做了它所说的一切来让它工作,但是我不能让排序真正发生。我甚至检查过它是否出错,但我什么也没得到

两个管道发送和接收相同的数字,但它们从未被分类。我错过了什么

int pipe1[2], pipe2[2];
pid_t childID;

if (pipe(pipe1) < 0 || pipe(pipe2) < 0) {
    perror("pipe");
    exit(EXIT_FAILURE);
    }

childID = fork();

if (childID < 0) {      
//Child Process Failure
    perror("fork");
    exit(EXIT_FAILURE);
}
else if (childID == 0){                                 
//Child Process Instructions
    cout << "Sent Numbers: " << endl;
    //Closes Unused Pipes
    close(pipe1[WRITE_END]);
    close(pipe2[READ_END]);

    //Dups Over the Others, then closes them
    dup2(pipe1[READ_END], STDIN_FILENO);
    close(pipe1[READ_END]);
    dup2(pipe2[WRITE_END], STDOUT_FILENO);
    close(pipe2[WRITE_END]);

    int fail = execlp("sort", "sort", "-nr", (char *)NULL);
    cout << fail << endl;
    }
else {                                                  
    //Parent Process Instructions
    //Close Unused Pipes
    close(pipe1[READ_END]);
    close(pipe2[WRITE_END]);

    srand(randSeed);
    cout << "Random Numbers: " << endl;
    for (int i = 0; i < nWorkers; i++){     
    //Generate nWorker numbers, then Write
        randNumbers[i] = rand() % (sleepMax - sleepMin + 1) + sleepMin;
        write(pipe1[WRITE_END], &randNumbers[i], sizeof(randNumbers[i]));
        cout << randNumbers[i] << endl;
    }
    close(pipe1[WRITE_END]);
    wait(NULL);
    cout << "SORTED NUMBERS:" << endl;

    double sortedNumbers[nWorkers];
    int n;

    for(int k = 0; k < nWorkers; k++) {
    n = read(pipe2[READ_END], &sortedNumbers[k], sizeof(sortedNumbers[k]));
    cout << sortedNumbers[k] << ", " << n << endl;
    }
}
intpipe1[2],pipe2[2];
pid_t childID;
如果(管道(管道1)<0 | |管道(管道2)<0){
佩罗(“管道”);
退出(退出失败);
}
childID=fork();
如果(childID<0){
//子进程失败
佩罗尔(“福克”);
退出(退出失败);
}
如果(childID==0){
//子进程指令
cout
sort(1)
希望它的输入是ASCII字符串,而不是原始二进制数。当您使用
write(2)
传递数据时,这是将数字的原始二进制表示形式写入管道,这不是您想要的。您需要将数字转换为其字符串表示形式

一种方法是使用打开管道顶部的stdio流。然后可以使用
fprintf
写入格式化数据:

FILE *childInput = fdopen(pipe1[WRITE_END], "w");
if (childInput == NULL) { /* Handle error */ }
for (...)
{
    ...
    fprintf(childInput, "%d\n", randNumbers[i]);
}
fclose(childInput);
同样,在读取子对象的输出时,也需要执行相同的操作:

FILE *childOutput = fdopen(pipe2[READ_END], "r");
if (childOutput == NULL) { /* Handle error */ }
while (fscanf(childOutput, "%d", &sortedNubers[i]) == 1)
{
    ...
}
fclose(childOutput);

如何创建管道?execlp的原型是
int execlp(const char*file,const char*arg,…)
,因此它不能使用“sort”和“sort”作为第一个和第二个参数。我认为“sort”和“sort”作为前两个参数正是您想要的:第一个参数是程序名,第二个参数是argv[0]?添加了我是如何创建管道的,我相信它们很好,对吗?我删除了第一个“排序”,但它仍然不起作用。应该有什么替代呢?这些是你的管道定义,但没有任何东西能将它们变成实际的管道而不是整数数组。smocking也提出了一个好的观点;你通常需要给出可执行文件的完整路径;它不像bash脚本。它似乎在起作用,但我没有收到返回w的数字创建日期:随机数:12 6 5 9 1 10 1 2 11排序数:6.95314e-310 6.95314e-310 6.95314e-310 3.95253e-323 6.95314e-310 6.95314e-310 6.95314e-310 0 6.95314e-310我知道了!我把RandNumber和SortedNumber都设置为双精度,我把它们改为常规整数。现在它排序了!非常感谢!