我的操作系統類中的一個賦值需要我通過在同一程序中遞歸調用exec來構建二進制進程樹。目標是將一些任意任務分解成單獨的進程。父母應該通過未命名的管道與孩子以及父母的孩子進行交流。這個想法是,父母發送每個孩子一半的工作,這種遞歸繼續下去,直到滿足基本情況下,傳遞給每個孩子的字符串的長度爲< = 2.然後,孩子處理這些數據並將結果發回通過管道傳遞給父母。Pipe,Fork和Exec - 父子進程之間的雙向通信
爲了更好地理解雙向通信如何與c中的管道協同工作,我在創建了下面的簡單程序,然後再進行實際任務。父母從不讀取子進程中的數據。我期待輸出...
in parent |收到的消息:測試
相反,當我打印我得到...
在父母|收到的消息:
看起來buff是空的,並且沒有從子進程讀取。有人可以解釋我在做什麼錯誤和/或
- 寫從父
- 在exec'd孩子
- 從寫回父母由父母讀exec'd孩子的標準方法exec'd孩子
- 在父母
我需要使用EXEC從exec'd孩子讀(),管(),fork()的。謝謝。
/**
* *********************************
* two_way_pipes.c
* *********************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define PARENT_READ read_pipe[0]
#define PARENT_WRITE write_pipe[1]
#define CHILD_WRITE read_pipe[1]
#define CHILD_READ write_pipe[0]
#define DEBUGGING 1
int main(int argc, char **argv) {
char buff[5];
// in the child process that was exec'd on the orginal call to two_way_pipes
if(argc == 2) {
read(STDIN_FILENO, buff, 4); // this should read "test" from stdin
buff[4] = '\0';
fprintf(stdout, "%s\n", buff); // this should right "test" to stdout and be read by the parent process
// int the root process, the original call to two_way_pipes with no args
} else {
int pid;
int read_pipe[2];
int write_pipe[2];
pipe(read_pipe);
pipe(write_pipe);
pid = fork();
// parent process
if(pid > 0) {
close(CHILD_READ);
close(CHILD_WRITE);
write(PARENT_WRITE, "test", 4); // attempting to write this to the child
struct timeval tv;
fd_set readfds;
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(PARENT_READ, &readfds);
select(PARENT_READ + 1, &readfds, NULL, NULL, &tv);
if(FD_ISSET(PARENT_READ, &readfds)) {
read(PARENT_READ, buff, 4); // should read "test" which was written by the child to stdout
buff[4] = '\0';
close(PARENT_READ);
close(PARENT_WRITE);
fprintf(stderr, "in parent | message received: %s\n", buff); // "test" is not in buff
}
// child process
} else if(pid == 0) {
close(PARENT_READ);
close(PARENT_WRITE);
dup2(CHILD_READ, STDIN_FILENO);
dup2(CHILD_WRITE, STDOUT_FILENO);
close(CHILD_READ);
close(CHILD_WRITE);
char *argv2[] = {"some random arg to make sure that argc == 2 in the child", NULL};
execvp("two_way_pipes", argv2);
_exit(0);
// error forking child process
} else {
fprintf(stderr, "error forking the child\n");
}
}
}
更新
根據喬納森的回答我修改了ARG2陣列傳遞到execvp到...
char *argv2[] = {"two_way_pipes", "1", NULL};
execvp("two_way_pipes", argv2);
這並沒有解決問題。父母仍然無法從客戶端讀取「測試」。然而,爲了迴應喬納森的回答和威廉的評論,我開始調整我的執行呼叫,並由於某種原因將其改爲下面的行顯示工作。
execl("two_way_pipes", "two_way_pipes", "1", NULL);
我很樂意接受任何答案,解釋爲什麼execvp調用不起作用,但execl調用做了。
你的exevp成功了嗎?嘗試用'perror(「execvp」)替換_exit(0)' –
感謝William。我用perror(「execvp」)替換了_exit(0)調用。該錯誤消息從未打印過,但我開始調整我的EXEC調用,並出於某種原因將調用改爲execl(「two_way_pipes」,「two_way_pipes」,「1」,NULL);解決了這個問題。 –
此代碼因此錯過了測試系統調用的結果。不這樣做會使測試和調試變得困難並且程序變得虛弱。請看我的答案。 – alk