我有一个作业,需要在头文件中声明一个管道。我真的不知道该怎么做。这可能是一个非常愚蠢的问题,我可能会遗漏一些明显的东西。如果您能为我指明正确的方向,我将不胜感激。
感谢您的宝贵时间。
编辑:
很抱歉问题如此模糊。也许我需要加强对管道的理解。
我正在尝试在两个子进程之间创建一个管道。一个 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()
并调用 sender
和 receiver
函数。
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/