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

标签 c header pipe declare

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

感谢您的宝贵时间。

编辑:

很抱歉问题如此模糊。也许我需要加强对管道的理解。

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

我想我不太明白当我写这样的东西时会发生什么:

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() 迭代都会收到错误“错误文件描述符”。我尝试在网上搜索自己解决这个问题,但我认为我对这些 Material 的了解还不够。任何方向将再次不胜感激。到目前为止,每个做出贡献的人都做得非常出色,非常感谢。另外,如果看起来我只是让你帮我做作业,那么我是在付出诚实的努力,而这并不是作业的全部。

编辑3:

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

编辑4: 我现在已经想通了一切。感谢大家的帮助。我唯一仍然好奇的是我是否能以某种方式获取父进程的状态。我已经使用 wait() 系统调用从子进程收集了状态,并且想知道如何检索父进程的状态。

最佳答案

下面是一个程序示例,该程序创建管道,然后 fork 进程并调用父级中的发送方函数和子级中的接收方函数。管道创建和文件描述符位于一个源代码文件中,并带有关联的头文件,发送方和接收方也是如此。 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() 函数的原型(prototype)

#ifndef SENDER_H
#define SENDER_H

void sender(void);

#endif

发件人.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 中。 pipeline.h 文件为文件描述符提供了 extern 声明,以便发送者和接收者文件可以访问它们(更好的编程实践是为管道中的这些文件描述符提供“getter”函数) .h,以便 sender()receiver() 不访问全局变量)。

发送方和接收方在关闭不需要的文件描述符后,使用 pipe_fd 数组对管道进行写入或读取。 main() 函数通过调用管道创建函数将所有这些连接在一起,然后执行 fork 并根据它是父级还是子级分别调用发送者或接收者。

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

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

这一切都有意义吗?

关于c - 如何在头文件中声明管道? (在C中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2458350/

相关文章:

javascript - 在 Node.js 中使用流来缓冲 HTTP 通信

windows - 由于未初始化的数据指针,管道进入 SET/P 失败?

c - 给定一个位掩码,如何计算位移计数

c - 使用指向数组层的指针遍历数组层

c# - 如何从 C# 更改 WPF 中 ListView 的列标题的文本?

php - 如何在低于 5.3 的 PHP 中删除 header ?

c - 在 Makefile 中运行 unix 命令以解析文本并将其传递给链接行作为定义 -D

在 C 中检查对 _Generic() 选择的支持

Python:创建值与列名匹配的数据框

bash - 为什么在 bash 中使用管道命令与 && 连接命令时得到不同的结果?