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

发布于 2024-08-25 08:51:01 字数 1465 浏览 9 评论 0原文

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

感谢您抽出时间。

编辑:

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

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

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

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

编辑3:

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

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

I have an assignment in which I need to declare a pipe in a header file. I really have no idea how to do this. It might be a really stupid question and I might be missing something obvious. If you could point me in the right direction I would greatly appreciate it.

Thanks for your time.

EDIT:

Sorry about the question being so vague. Maybe I need to reinforce my understanding of pipes.

I'm trying to create a pipe between two child processes. One child will write random characters into the pipe while the other child will read characters out of the pipe.

I guess I don't really understand what happens when I write something like:

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

Am I right in saying that the writing and reading file descriptors for the pipe are put into fd[0] and fd[1] respectively? If in one of the child processes I close fd[1], that child could be thought of as my writer, correct?

EDIT 2:

Okay, it looks as if I pretty much have everything figured out and done, except I am getting an error pertaining to the file descriptors.

My code looks like this: (This is only the code relating to the pipe)

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");
}

After executing the code, I get an error for every iteration of read() and write() with the error "Bad file descriptor". I've tried searching online to solve this myself, but I do not think I know enough about this material in order to do so. Any direction would be greatly appreciated once again. Everybody that has contributed has done a wonderful job so far, thank you very much. Also, if it looks like I'm just having you do my homework for me, I'm putting forth an honest effort and this isn't the entirety of the assignment.

EDIT 3:

Is the write() system call writing to standard output? What if I only want the contents to be printed after the reader reads them out of the pipe? How do I write them into the pipe without it writing them to standard output?

EDIT 4:
I've figured everything out now. Thanks for all of the help everybody. The only thing I'm still curious about is if I could somehow get the status of the parent process. I've collected the statuses from the child process using the wait() system call and was wondering how to retrieve the status of the parent process.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

像你 2024-09-01 08:51:01

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

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

#ifndef PIPE_H
#define PIPE_H

extern int pipe_fd[2];

void create_pipe(void);

#endif

pipeline.c - 包含 pipe_fd< 的实际定义/code> array:-

#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;
   }

希望你能遵循所有这是代码中的,但如果没有,这里有一些额外的解释。

pipeline.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

这一切都有意义吗?

Here's an example of a program that creates a pipe and then forks the process and calls a sender function in the parent and a receiver in the child. The pipe creation and file descriptors are in one source code file with an associated header file, as are the sender and receiver. The main file requests the pipe be created then does the fork() and calls the sender and receiver functions.

pipe.h - this contains the extern declaration for the pipe file descriptors as well as the declaration of the function that creates the pipe:-

#ifndef PIPE_H
#define PIPE_H

extern int pipe_fd[2];

void create_pipe(void);

#endif

pipe.c - contains the actual definition of the pipe_fd array:-

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

int pipe_fd[2];

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

sender.h - declares the prototype for the sender() function

#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 - mirror image of sender

#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 - ties it all together

#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;
   }

Hopefully you can follow all this from the code but if not here's a little extra explanation.

The create_pipe() function in pipe.c creates a pipe and puts the two file descriptors into file_fd. The pipe.h file provides an extern declaration for the file descriptors so that they can be accessed by the sender and receiver files (better programming practice would be to provide "getter" functions for these file descriptors in pipe.h so that sender() and receiver() are not accessing global variables).

Sender and Receiver use the pipe_fd array to either write or read from the pipe after they close the file descriptor that they don't need. The main() function ties it all together by calling the pipe creation function and then doing the fork and calling sender or receiver depending on whether it is the parent or child respectively.

Running this as a complete program should get you the following output (although of course the PIDs you get will be different):-

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

Does all that make sense?

深居我梦 2024-09-01 08:51:01

你的问题几乎不可能含糊不清,但我猜

extern int myPipe[2];

Your question is almost impossibly vague, but I'm going to guess

extern int myPipe[2];

?

×纯※雪 2024-09-01 08:51:01

如果您打算 fork() 创建两个进程,那么您的“int fd[2]; pipeline(fd);”将按照您所描述的方式工作。

即在一个进程中使用 fd[0],在另一个进程中使用 fd[1]。

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

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

If you intend to fork() to create the two processes then your "int fd[2]; pipe(fd);" will work as you described.

i.e. use fd[0] in one process and fd[1] in the other.

However, if you're not going to fork then you're probably going to have to create a pipe in the filesystem and communicate through this.

Use mkfifo to create your pipe and then open it for reading in one process and open it for writing in the other.

秋叶绚丽 2024-09-01 08:51:01

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

Why do you need to do it in a header file?
You just call pipe() from your program.
Then call fork().
As a result you have two processes accessing the same pipe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文