2

ヘッダーファイルでパイプを宣言する必要がある割り当てがあります。私は本当にこれを行う方法がわかりません。それは本当にばかげた質問かもしれませんし、私は明白な何かを見逃しているかもしれません。私を正しい方向に向けていただければ幸いです。

御時間ありがとうございます。

編集:

質問があいまいでごめんなさい。たぶん、パイプについての理解を深める必要があります。

2つの子プロセス間にパイプを作成しようとしています。1人の子はランダムな文字をパイプに書き込み、もう1人の子はパイプから文字を読み取ります。

私は次のようなものを書いたときに何が起こるかを本当に理解していないと思います:

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

パイプの書き込みファイル記述子と読み取りファイル記述子がそれぞれfd[0]とに入れられていると言っているのは正しいfd[1]ですか?子プロセスの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()を繰り返すたびにエラーが発生し、「Badfiledescriptor」というエラーが発生します。私はこれを自分で解決するためにオンラインで検索しようとしましたが、そうするためにこの資料について十分に知っているとは思いません。どんな方向でももう一度大歓迎です。これまで貢献してくださった皆様、素晴らしい仕事をしていただき、誠にありがとうございます。また、宿題をしてもらうだけのようであれば、正直に頑張っていますが、それだけではありません。

編集3:

write()システムコールは標準出力への書き込みですか?リーダーがパイプから内容を読み取った後にのみ内容を印刷したい場合はどうなりますか?標準出力に書き込まずにパイプに書き込むにはどうすればよいですか?

編集4: 私は今すべてを理解しました。皆様のご協力に感謝いたします。私がまだ興味を持っているのは、どういうわけか親プロセスのステータスを取得できるかどうかだけです。wait()システム呼び出しを使用して子プロセスからステータスを収集しましたが、親プロセスのステータスを取得する方法を考えていました。

4

4 に答える 4

3

以下は、パイプを作成してプロセスをフォークし、親で送信側関数を呼び出し、子で受信側関数を呼び出すプログラムの例です。パイプの作成とファイル記述子は、送信側と受信側と同様に、関連付けられたヘッダー ファイルを含む 1 つのソース コード ファイルにあります。mainファイルは、パイプの作成を要求し、andを実行してand関数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

送信者.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() 関数は、パイプを作成し、2 つのファイル記述子を に配置しfile_fdます。pipe.h ファイルはextern、ファイル記述子の宣言を提供して、送信側ファイルと受信側ファイルからアクセスできるようにします (より適切なプログラミング方法は、pipe.h でこれらのファイル記述子に「ゲッター」関数を提供して、sender()receiver()がアクセスしないようにすることです)。グローバル変数)。

Sender と Receiver は、pipe_fd必要のないファイル記述子を閉じた後、配列を使用してパイプから書き込みまたは読み取りを行います。このmain()関数は、パイプ作成関数を呼び出してから fork を実行し、それが親であるか子であるかに応じて送信者または受信者を呼び出すことで、すべてを結び付けます。

これを完全なプログラムとして実行すると、次の出力が得られます (もちろん、取得する PID は異なります):-

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

それはすべて意味がありますか?

于 2010-03-17T00:41:28.853 に答える
1

あなたの質問はほとんど不可能に曖昧ですが、私は推測するつもりです

extern int myPipe[2];

于 2010-03-16T21:42:49.133 に答える
0

2 つのプロセスを作成するために fork() を使用する場合は、「int fd[2]; pipe(fd);」を使用します。あなたが説明したように動作します。

つまり、一方のプロセスで fd[0] を使用し、もう一方のプロセスで fd[1] を使用します。

ただし、フォークしない場合は、おそらくファイルシステムにパイプを作成し、これを介して通信する必要があります。

mkfifo を使用してパイプを作成し、それを 1 つのプロセスで読み取り用に開き、別のプロセスで書き込み用に開きます。

于 2010-03-16T21:52:52.823 に答える
0

なぜヘッダーファイルでそれを行う必要があるのですか? プログラムから pipe() を呼び出すだけです。次に fork() を呼び出します。その結果、2 つのプロセスが同じパイプにアクセスします。

于 2010-03-16T21:52:55.903 に答える