【发布时间】:2019-05-11 19:41:10
【问题描述】:
我很难弄清楚父亲和孩子之间的沟通问题。当我运行主程序时,似乎什么也没发生。 我确实在网上搜索了解决方案,但到目前为止没有任何帮助。 我知道我在这里发布了很多代码但是从我的旧帖子中关于同样的问题人们一次又一次地让我阅读这个人但是仍然,有些东西不在这里,我不知道到底是什么。 希望大家帮帮我
#include <stdio.h>
#include <stdlib.h> //for exit
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> //for sleep(),execvp()
#include <ctype.h>
#include <fcntl.h>
#define IN 0
#define OUT 1
#define SIZE 81
#define EXEC "./child"
int main(int argc, char * argv[])
{
int fd[2];
int fdr; // file descriptors
int i;
char result[3];
pid_t pid;
char charMatrix[SIZE] ={ 0 };
int matrix[9][9]={0};
if (argc < 2)
{
printf("No files added, abort program\n");
exit(EXIT_FAILURE);
}
if (pipe(fd) == -1)
{
printf("Pipe Failed");
return 1;
}
fdr = open(argv[1], O_RDONLY); // open files
if (fdr < 0)
{ //validation for error
perror("failed to open input or output files");
exit(EXIT_FAILURE);
}
char c;
charMatrix[81] = '\0';
i=0;
int j=0;
while (read(fdr, &c, 1)) // read/write a single char
{ // from/to the files
if (c != ' ' && c != '\n')
{
charMatrix[i++]=c-'0';
}
}
close(fdr); // close the file
int index=0; //convert to matrix
for (i = 0; i < 9; i++) { /* Iterate of each row */
for (j = 0; j < 9; j++) { /* In each row, go over each col element */
matrix[i][j]=charMatrix[index++];
}
}
for (i = 0; i < 9; i++) {// Iterate of each row
for (j = 0; j < 9; j++) { //In each row, go over each col element
printf("%d ", matrix[i][j]);// Print each row element
}
printf("\n");// Finish a row, start a new line
}
pid = fork();
if (pid < 0)
{
fputs("error in fork", stderr);
exit(EXIT_FAILURE);
}
//child
if(pid == 0)
{
close(fd[0]);
close(STDOUT_FILENO);
dup(fd[1]);
execl(EXEC, charMatrix, NULL);
}
//parent
else{
close(fd[1]);
close(STDIN_FILENO);
dup(fd[0]);
read(fd[0], &result, sizeof(result));
wait(NULL);
}
exit(EXIT_SUCCESS);
}
执行的文件
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char * argv[]){
int matrix[9][9];
char charMatrix[81];
char ans;
int i, j;
printf("got here");
read(0,&charMatrix,sizeof(charMatrix));
int index=0; //convert to matrix
for (i = 0; i < 9; i++) { /* Iterate of each row */
for (j = 0; j < 9; j++) { /* In each row, go over each col element */
matrix[i][j]=charMatrix[index++];
}
}
write(4, "a", sizeof(char));
for (i = 0; i < 9; i++) { /* Iterate of each row */
for (j = 0; j < 9; j++) { /* In each row, go over each col element */
printf("%d ", matrix[i][j]); /* Print each row element */
}
printf("\n"); /* Finish a row, start a new line */
}
exit(0);
}
在建议的解决方案之后,我尝试添加另一个孩子,但仍然出错。 这是代码和我如何看待它的解释
dup2(pipe1[0], STDIN_FILENO); //makes the input( 0 in the stack) to the pipe1[0] which means point to its
close(pipe1[0]);
close(pipe1[1]); //closing before pointes
dup2(pipe2[1], STDOUT_FILENO); //makes the output (1 in the stack) to point pip1[1]
close(pipe2[0]);
close(pipe2[1]);//closing
execl(EXEC, EXEC, NULL);//exec
我尝试用新管道对另一个孩子做同样的事情,但没有成功。我将父亲 pipe1 复制到第二个孩子的 pipe3 的答案
//--------------------------------------------- ----------------------//
#define SIZE 81
#define EXEC "./child"
#define EXEC2 "./child2"
int main(int argc, char *argv[])
{
char charMatrix[SIZE] = { 0 };
int matrix[9][9] = { 0 };
char chilesStatus[3]={0};
if (argc != 2)
{
fprintf(stderr, "Usage: %s matrix file \n", argv[0]);
exit(EXIT_FAILURE);
}
int fdr = open(argv[1], O_RDONLY);
if (fdr < 0)
{
perror("failed to open input or output files");
exit(EXIT_FAILURE);
}
char c;
int k = 0;
while (read(fdr, &c, 1) == 1 && k < (int)sizeof(charMatrix))
{
if (c != ' ' && c != '\n')
charMatrix[k++] = c - '0';
}
close(fdr);
int index = 0;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
matrix[i][j] = charMatrix[index++];
}
printf("Input matrix:\n");
for (int i = 0; i < 9; i++)
{
printf("P: ");
for (int j = 0; j < 9; j++)
printf(" %d", matrix[i][j]);
printf("\n");
}
fflush(stdout); // Making sure output is flushed even if it is going to a pipe
int pipe1[2];
int pipe2[2];
int pipe3[2];
int pipe4[2];
if (pipe(pipe1) == -1 || pipe(pipe2) == -1 || pipe(pipe3) == -1) //pipe validation
{
perror("Pipe failed");
exit(EXIT_FAILURE);
}
pid_t fChild = fork();
if (fChild < 0)
{
perror("Fork failed");
exit(EXIT_FAILURE);
}
if (fChild == 0)
{
dup2(pipe1[0], STDIN_FILENO);
close(pipe1[0]);
close(pipe1[1]);
dup2(pipe2[1], STDOUT_FILENO);
close(pipe2[0]);
close(pipe2[1]);
execl(EXEC, EXEC, NULL);
int errnum = errno;
fprintf(stderr, "Failed to execute '%s' (%d: %s)\n", EXEC, errnum, strerror(errnum));
exit(EXIT_FAILURE);
}
else
{
pid_t sChild = fork();
if(sChild==0)
{
dup2(pipe2[0], STDIN_FILENO);
close(pipe2[0]);
close(pipe2[1]);
dup2(pipe3[1], STDOUT_FILENO);
close(pipe3[0]);
close(pipe3[1]);
execl(EXEC2, EXEC2, NULL);
int errnum = errno;
fprintf(stderr, "Failed to execute '%s' (%d: %s)\n", EXEC, errnum, strerror(errnum));
exit(EXIT_FAILURE);
}
else
{
}
close(pipe2[0]);
close(pipe1[0]);
if (write(pipe1[1], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
{
perror("failed to write to child");
exit(EXIT_FAILURE);
}
if (write(pipe1[2], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
{
perror("failed to write to child");
exit(EXIT_FAILURE);
}
close(pipe1[1]);
close(pipe2[1]);
close(pipe3[1]);
char result[3];
int nbytes = read(pipe2[0], &result, sizeof(result));
int nbytes2 = read(pipe3[0], &result, sizeof(result));
if (nbytes <= 0 ||nbytes2 <= 0)
{
perror("Failed to read from pipe");
exit(EXIT_FAILURE);
}
close(pipe2[0]);
close(pipe3[0]);
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("Child %d exited with status 0x%.4X\n", corpse, status);
printf("Received '%.*s' from child\n", nbytes, result);
}
return(EXIT_SUCCESS);
}
【问题讨论】:
-
注意
printf("got here");作为跟踪操作几乎没用;您必须以换行符结束它以使其远程可靠 - 或添加fflush(stdout);(最好也带有换行符)。 -
使用
read(0, …)是合理的——这是从标准输入读取,也称为STDIN_FILENO。使用write(4, …)不太合理。您当然应该安排程序写入标准输出(并且跟踪输出可能应该写入标准错误 - 事实上,即使标准输出和标准错误都连接到终端,这通常也是一个好主意)。如果您不将子项的标准输出安排为返回父项的管道,则应为程序提供一个参数来告诉它要在哪个文件描述符上写入。 -
另外,注意如果你同时有parent向child发送消息,child向parent发送消息,则需要两个管道(四个文件描述符),并且需要大量的关闭操作.尝试使用一个管道进行双向通信是一种挫败感——不要这样做。
-
您在
execl()中将矩阵作为程序名称传递,这很古怪。如果矩阵中有任何零也是不可靠的 - 它们被映射到空字节,因此您无法访问矩阵中的任何内容。您的孩子试图从标准输入中读取矩阵;您永远不会向其标准输入写入任何内容。 -
我很困惑,我什至不知道从哪里开始。你修复它的可能性是什么?,我想我会更好地理解它