我有一个程序,它会分叉一个孩子,并希望它与其父母沟通。但是,在关闭孩子的写端时,我似乎遇到了错误。
程序在孩子内部和if (close(pfd1[1]) == -1)
当孩子想要关闭写结束时,显然会失败。为什么呢?
/* Note: working under the assumption that the messages are of equal length */
int main(int argc, char * argv[])
{
int pfd1[2];
char buf[BUF_SIZE];
//checks pipefd1
if (pipe(pfd1) == -1)
{
printf("Error opening pipe 1!\n");
exit(1);
}
printf("Pipe opened with success. Forking ...\n");
// child 1
switch (fork())
{
case -1:
printf("Error forking child 1!\n");
exit(1);
case 0:
printf("\nChild 1 executing...\n");
/* close writing end of first pipe */
if (close(pfd1[1]) == -1)
{
printf("Error closing writing end of pipe 1.\n");
_exit(1);
}
/* read from pipe 1 */
if (read(pfd1[0], buf, 2000))
{
printf("Error reading to pipe 1.\n");
_exit(1);
}
/* close reading end of first pipe */
if (close(pfd1[1]) == -1)
{
printf("Error closing writing end of pipe 1.\n");
_exit(1);
}
printf("Message received child ONE: %s", buf);
printf("Exiting child 1...\n");
_exit(0);
default: //parent breaks just out
break;
}
printf("inside parent\n");
int child = 1;
char *message = "Hey child1, this is your parent speaking";
if(child == 1)
{
//close read end of pipe
if(close(pfd1[0]) == -1)
{
printf("Error closing reading end of the pipe.\n");
exit(EXIT_FAILURE);
}
printf("Parent closed read end of pipe1\n");
//read end is closed, now write to child
if(write(pfd1[1], message, strlen(message)))
{
printf("Error writing to the pipe.");
_exit(EXIT_FAILURE);
}
printf("Writing to child1 succeeded\n");
}
if (wait(NULL) == -1)
{
printf("Error waiting.\n");
exit(EXIT_FAILURE);
}
if (wait(NULL) == -1)
{
printf("Error waiting.\n");
exit(EXIT_FAILURE);
}
printf("Parent finishing.\n");
exit(EXIT_SUCCESS);
}
答案 0 :(得分:3)
首先,在孩子的情况下,你试图两次关闭管道的书写端。我想第二次调用close(2)
意味着关闭阅读结束,如上面的评论所述:
/* close reading end of first pipe */
if (close(pfd1[0]) == -1)
{
printf("Error closing writing end of pipe 1.\n");
_exit(1);
}
除此之外,请注意read(2)
和write(2)
都返回实际读取或写入的字节数;在出现错误的情况下,返回值为-1
,因此您的错误检查条件也应该修复,例如:
/* read from pipe 1 */
if (read(pfd1[0], buf, 2000) < 0) {
printf("Error reading to pipe 1.\n");
_exit(1);
}
和
//read end is closed, now write to child
if(write(pfd1[1], message, strlen(message)) < 0) {
printf("Error writing to the pipe.");
_exit(EXIT_FAILURE);
}
答案 1 :(得分:1)
根据钓鱼教学原则,诊断此类问题的一种好方法是检查错误是什么,并打印更多信息。这是我经常放入头文件并使用的技术:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* This declaration and macro would really go into a header file: */
void fatal_error_helper( const char* msg, const char* sourcefile, int lineno, const char* syserr );
#define fatal_system_error(m) \
fatal_error_helper( (m), __FILE__, __LINE__, strerror(errno) )
/* This function definition would really go into a .c file: */
void fatal_error_helper( const char* const msg,
const char* const sourcefile,
const int lineno,
const char * const syserr )
{
fflush(stdout); /* Don't cross the streams! */
fprintf( stderr,
"%s at %s:%d: %s. Program terminated.\n",
msg, sourcefile, lineno, syserr
);
exit(EXIT_FAILURE);
}
/* Test driver: */
FILE* fails_to_open_file( const char* filename )
/* Returns a FILE* to an open file. If the operation fails, prints an
* error message and terminates the program.
*/
{
/* Do this in general before calling the function whose error value
* you check. Otherwise, you might report the wrong error message
* from an earlier call and really confuse someone.
*/
errno = 0;
FILE* result = NULL;
result = fopen(filename, ""); /* Fails. */
if (!result)
fatal_system_error("Failed to open file");
return result;
}
int main(void)
{
fails_to_open_file("nonexistent.file");
return EXIT_SUCCESS;
}
这会显示错误消息,例如:Failed to open file at prog.c:26: Invalid argument. Program terminated.