如何在头文件中声明管道? (在C中)

时间:2010-03-16 21:37:55

标签: c header pipe declare

我有一个赋值,我需要在头文件中声明一个管道。我真的不知道该怎么做。这可能是一个非常愚蠢的问题,我可能会遗漏一些明显的东西。如果你能指出我正确的方向,我将非常感激。

感谢您的时间。

修改

很抱歉这个问题太模糊了。也许我需要加强对管道的理解。

我正在尝试在两个子进程之间创建一个管道。一个孩子会将随机字符写入管道,而另一个孩子将从管道中读取字符。

我想我真的不明白当我写下这样的内容时会发生什么:

int fd[2];
pipe = pipe(fd);

我是否正确地说管道的写入和读取文件描述符分别放入fd[0]fd[1]?如果在其中一个子进程中我关闭fd[1],那么这个孩子可以被认为是我的作家,对吗?

编辑2:

好吧,看起来我几乎已经完成了所有事情,除了我收到与文件描述符有关的错误。

我的代码如下所示:(这只是与管道相关的代码)

proj2.h

extern int fd[2];

proj2.c

int fd[2];
pipe(fd);

writer.c

close(fd[0]);
result = write(fd[1], &writeBuffer, sizeof(writeBuffer));
if(result < 0){
    perror("Write");
}

reader.c

close(fd[1]);
result = read(fd[0], &readBuffer, sizeof(readBuffer))
if(result < 0){
    perror("Read");
}

执行代码后,我在read()和write()的每次迭代中都会收到错误,错误为“Bad file descriptor”。我已经尝试过在线搜索以解决这个问题,但我认为我不太了解这些材料。任何方向将再次受到高度赞赏。到目前为止,所有贡献的人都做得很好,非常感谢你。另外,如果看起来我只是让你为我做功课,我会做出诚实的努力,这不是作业的全部内容。

编辑3:

write()系统调用是否写入标准输出?如果我只想在阅读器将它们从管道中读出后打印内容怎么办?如果不将它们写入标准输出,如何将它们写入管道?

编辑4: 我现在想出了一切。感谢所有人的帮助。我唯一感到好奇的是,如果我能以某种方式获得父进程的状态。我使用wait()系统调用从子进程收集了状态,并想知道如何检索父进程的状态。

4 个答案:

答案 0 :(得分:3)

这是一个程序示例,它创建一个管道,然后分叉该进程并调用父项中的发送方函数和子项中的接收方。管道创建和文件描述符在一个源代码文件中,具有关联的头文件,发送方和接收方也是如此。 main文件请求创建管道然后执行fork()并调用senderreceiver函数。

pipe.h - 它包含管道文件描述符的extern声明以及创建管道的函数声明: -

#ifndef PIPE_H
#define PIPE_H

extern int pipe_fd[2];

void create_pipe(void);

#endif

pipe.c - 包含pipe_fd数组的实际定义: -

#include "pipe.h"
#include <unistd.c>

int pipe_fd[2];

void create_pipe(void)
   {
   pipe(pipe_fd);
   }

sender.h - 声明sender()函数的原型

#ifndef SENDER_H
#define SENDER_H

void sender(void);

#endif

sender.c: -

#include "sender.h"
#include "pipe.h"
#include <unistd.h>
#include <stdio.h>

void sender(void)
   {
   char buf[]="Hello world";

   printf("Sender: PID = %d\n", getpid());
   close(pipe_fd[0]);
   write(pipe_fd[1], buf, sizeof(buf));
   }

receiver.h: -

#ifndef RECEIVER_H
#define RECEIVER_H

void receiver(void);

#endif

receiver.c - 发件人的镜像

#include <stdio.h>
#include <unistd.h>
#include "receiver.h"
#include "pipe.h"

void receiver(void)
   {
   int bytes;
   char buf[101];

   printf("Receiver: PID = %d\n", getpid());

   close(pipe_fd[1]);
   bytes = read(pipe_fd[0], buf, 100);
   buf[bytes]='\0';
   printf("Receiver got: %s\n", buf);
   }

main.c - 将它们联系在一起

#include "pipe.h"
#include "sender.h"
#include "receiver.h"
#include <sys/types.h>
#include <unistd.h>

void launch_sender_receiver(void)
   {
   pid_t forkpid;

   forkpid = fork();
   if (forkpid == 0)
      receiver(); /* child */
   else
      sender();
   }

int main(int argc, char* argv[])
   {
   create_pipe();
   launch_sender_receiver();
   return 0;
   }

希望您可以从代码中遵循所有这些,但如果不是,这里有一点额外的解释。

pipe.c中的create_pipe()函数创建一个管道并将两个文件描述符放入file_fd。 pipe.h文件为文件描述符提供extern声明,以便发送方和接收方文件可以访问它们(更好的编程实践是在pipe.h中为这些文件描述符提供“getter”函数。 sender()receiver()未访问全局变量。)

发件人和接收者使用pipe_fd数组在关闭不需要的文件描述符后从管道写入或读取。 main()函数通过调用管道创建函数然后执行fork并调用发送者或接收者(取决于它们是父节点还是子节点)将它们连接在一起。

将此作为一个完整的程序运行应该会得到以下输出(当然,你得到的PID会有所不同): -

Receiver: PID = 3285
Sender: PID = 3284
Receiver got: Hello world

一切都有意义吗?

答案 1 :(得分:1)

你的问题几乎不可能模糊,但我猜是

extern int myPipe[2];

答案 2 :(得分:0)

如果你想fork()创建两个进程,那么你的“int fd [2]; pipe(fd);”会像你描述的那样奏效。

即。在一个过程中使用fd [0]而在另一个过程中使用fd [1]。

但是,如果你不打算分叉,那么你可能不得不在文件系统中创建一个管道并通过它进行通信。

使用mkfifo创建管道然后打开它以便在一个进程中读取并打开它以便在另一个进程中写入。

答案 3 :(得分:0)

为什么需要在头文件中执行此操作? 您只需从程序中调用pipe()即可。 然后调用fork()。 因此,您有两个进程访问同一个管道。