我之前发布了一个关于using fork() and pipes in C 的问题。我稍微改变了设计,以便它读取常规的txt文件并对文件中的单词进行排序。到目前为止,这是我提出的:
for (i = 0; i < numberOfProcesses; ++i) {
// Create the pipe
if (pipe(fd[i]) < 0) {
perror("pipe error");
exit(1);
}
// fork the child
pids[i] = fork();
if (pids[i] < 0) {
perror("fork error");
} else if (pids[i] > 0) {
// Close reading end in parent
close(fd[i][0]);
} else {
// Close writing end in the child
close(fd[i][1]);
int k = 0;
char word[30];
// Read the word from the pipe
read(fd[i][0], word, sizeof(word));
printf("[%s]", word); <---- **This is for debugging purpose**
// TODO: Sort the lists
}
}
// Open the file, and feed the words to the processes
file_to_read = fopen(fileName, "rd");
char read_word[30];
child = 0;
while( !feof(file_to_read) ){
// Read each word and send it to the child
fscanf(file_to_read," %s",read_word);
write(fd[child][1], read_word, strlen(read_word));
++child;
if(child >= numberOfProcesses){
child = 0;
}
}
其中numberOfProcesses
是命令行参数。所以它的作用是它读取文件中的每个单词并将其发送到进程。但是,这不起作用。当我在子进程中打印单词时,它不会给我正确的输出。我是否正确地将文字写入/从管道中读取?
答案 0 :(得分:1)
在父级中,您编写strlen()
个字节,可能少于30个字节。但是,在孩子中,你总是尝试读取30个字节。您还必须NUL终止该单词,否则您可能会在printf()
语句中看到垃圾或失控字符串。
在子级中,您必须在字边界处解析和拆分输入,或者使用stdio作为@JonathanLeffler建议。当你使用stdio时,你可以免费获得所有这些缓冲和单词阅读。
int n;
char word[31];
/* Read the word from the pipe */
n = read(fd[i][0], word, sizeof(word) - 1);
if (n == -1) {
perror("read");
/* do error handling */
} else {
word[n] = 0;
printf("[%s]", word);
}
答案 1 :(得分:1)
单词是以错误的顺序打印还是交错?问题是,当你向管道写一个单词时,你期望处理该管道的过程立即被安排并打印该单词。然后,您希望主进程再次运行,并将下一个单词写入下一个管道等。
但这并不能保证会发生。在安排任何其他进程之前,您的主循环可能会将所有单词写入所有管道。这些流程可能未按您期望的顺序安排。并且printf调用可能会相互干扰,因此它们的输出会交错。
如果你真的想做你想要做的事情,那么Posix线程会更好。如果你只是想学习使用多个过程的东西,那么我想你有: - )