[英]How to make a UNIX pipe prompt for user input correctly?
我試圖讓UNIX管道正確提示用戶輸入。 我必須使用單個管道創建3個子進程。 每個子進程都要求用戶輸入一個整數並將其寫入管道。 父進程顯示所有三個整數以及將每個整數寫入管道的進程的進程ID。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char argv[]) {
int input = 0;
int pd[2];
int i =0;
int buffer[100];
int output = 0;
if (pipe(pd) == - 1) {
fprintf(stderr, "Pipe Failed");
}
for (i=0; i<3; i++) {
if (fork() == 0) { // child process
printf("\nMy process id is: %d", getpid());
printf("\nEnter an integer: ");
scanf("%d", &input);
if (write(pd[1], &input, sizeof(int)) == -1) {
fprintf(stderr, "Write Failed");
}
return (0); // Return to parent. I am not really sure where this should go
} // end if statement
} // I am not quite sure where the for loop ends
// Parent process
close(pd[1]); // closing the write end
for (i = 0; i < 3; i++) {
if (read(pd[0], &output, sizeof(int) )== -1) {
fprintf(stderr, "Read failed");
}
else {
buffer[i] = output;
printf("Process ID is: %d\n", pid);
}
}
printf("The numbers are %d, %d, %d", buffer[0], buffer[1], buffer[2]);
return(0);
}
編輯后,我現在得到輸出:
My process id is: 2897
Enter an integer: My process id is: 2896
Enter an integer:
My process id is: 2898
Enter an integer: 4
Process ID is: 2898
78
Process ID is: 2898
65
Process ID is: 2898
The numbers are 4, 78, 65
這離我們很近,但我還不確定如何讓父級等待子級進程。 當嘗試打印每個數字及其進程ID時,只會打印最新的進程ID。
所有printf語句在scanf語句之前執行,因此我無法鍵入任何內容,直到提示3次為止。
在任何給定時間,只有一個進程可以與用戶對話。 您需要進行安排,以使子級2在子級1完成之前不會執行任何操作,依此類推。 最簡單的方法是在派生下一個孩子之前,先讓每個孩子都擁有父wait()
。 編輯:看起來像這樣:
for (i = 0; i < 3; i++) {
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return 1;
} else if (pid == 0) {
// your existing child code goes here
} else {
// parent:
int status;
if (waitpid(pid, &status, 0) != pid) {
perror("wait");
return 1;
} else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
fprintf(stderr, "child %d unexpected exit %d\n", i, status);
return 1;
}
}
}
由於寫入管道的數據量非常短(總共少於PIPE_BUF
字節;保證PIPE_BUF
至少為512),因此可以放心地從管道中讀取數據,直到所有子項都退出為止。 如果孩子們發回更長的消息,情況就不會如此。
main
返回一個整數。 您的return;
第一個循環中的語句應return 0;
並且需要另一個return 0;
在最后(最后一次printf
)。
您的第一個for
循環在應該結束的地方結束,即在嵌套的if
語句之后。 您可以在其周圍放置另一組花括號-在for (...)
之后打開花括號,在您擁有// I am not quite sure
地方關閉花括號, // I am not quite sure
發表的評論-很多人會認為這種樣式更好,但是您不必。
if (read(pd[0]), &output, sizeof(int) )== -1)
^ // this is wrong
您的括號不正確,但我認為這是一個錯字。
您還只有在讀取失敗的情況下才更新緩沖區...應該是:
if (read(pd[0], &output, sizeof(int) )== -1) {
fprintf(stderr, "Read failed");
}
else {
buffer[i] = output;
}
但是,有許多方法可以改進此代碼。 查看其他答案,並在警告下編譯您的程序(-gcc帶有Wall)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.