0

コンシューマー (クライアント) 側をプロデューサー (サーバー) に開発するように依頼されました。プロデューサーはプロセスを作成し、コンシューマーが共有メモリを読み取ってプロセスを削除するまで待機し、プロセスを強制終了するために制御をプロデューサーに戻します。共有メモリブロックのシャットダウン。

スリープと待機の違いを調べたところ、 fork() が呼び出されるとすぐに子プロセスが実行を開始することがわかりました。

以下のコードは、プロセスの作成後のもので、それらが親プロセスであるかどうかを確認します。そうであれば、待機します(0)。*私の質問ですが、コンシューマ内のコードが実行され始める場所をどのように知ることができますか?また、それを戻すにはどうすればよいですか? *

else if(pid > 0)
                {
                    wait(0);
                }

以下は、プロデューサーが使用するメイン ループです。

int noToCreate = atoi(argv[2]); // (user inputs on cmd line "./prod 20 10 5" - 20 size of shared mem, 10 process to be created, 5 processes to be deleted)

while(*memSig != 2)
    {
        while(*memSig == 1)   // set memsignature to sleep while..
        {
            sleep(1);
        }

        for(B = 0; B < noToCreate; B++)     
        {
            pid = fork();

            if(pid == -1)
            {
                perror("Error forking");
                exit(1);
            }
            else if(pid > 0)
            {
                wait(0);
            }
            else
            {
                srand(getpid());

                while(x == 0)
                {
                    if(*randNum == 101)
                    {
                        *randNum = rand() % (100 - 

1) + 1;
                        *pidNum = getpid();

                        printf("priority: %d 

Process ID: %d \n", *randNum, *pidNum);

                        x = 1;
                    }
                    else
                    {
                        *randNum++;
                        *pidNum++;
                    }
                }
                exit(0);
            }
        } /* Closes main for loop */

        if(*memSig == 0)
        {
            *memSig = 1;
        }
    } /* Closes main while loop */

みんなありがとう:)

4

3 に答える 3

2

wait子が終了するまで親をブロックしますwaitpid。親に特定の子を待機させることができます。

子プロセスが終了すると、シグナルが設定されますSIG_CHILD

于 2013-08-05T08:52:17.280 に答える
2

fork 後の子プロセスの pid はゼロであるため、srand 関数の呼び出し時に子プロセスにいます。

もう 1 つの pid は、元のスレッドが子プロセスの終了を待機できるようにする子プロセス用のものです。プロセス間でデータを渡したい場合は、パイプの使用を検討してください。popen 呼び出しは 2 つのファイル記述子を返します。1 つは書き込み側、もう 1 つは読み取り側です。フォークと 2 つのプロセスが通信できるようになる前に、これを設定します。

于 2013-08-05T08:52:17.427 に答える
1

wait子が終了するまで親を待機させてから (waitpid特定の子を待機させるために使用することをお勧めします)、sleep引数として渡された時間が経過するとすぐに、プロセスをスリープ状態にして再開します。
どちらの呼び出しもプロセスをブロックします。
そして、子供がすぐに走るとは言われていません。これは不確定な行動です!

プロデューサーとコンシューマーの間でデータを渡したい場合は、パイプまたは *NIX ソケットを使用するexitか、単一の整数で十分な場合は子からの戻り値を使用します。

man waitを参照してください。マクロで子の戻り値を取得できますWEXITSTATUS

#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
    pid_t cpid, w;
    int status;

   cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

   if (cpid == 0) {            /* Code executed by child */
        printf("Child PID is %ld\n", (long) getpid());
        if (argc == 1)
            pause();                    /* Wait for signals */
        _exit(atoi(argv[1]));

   } else {                    /* Code executed by parent */
        do {
            w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
            if (w == -1) {
                perror("waitpid");
                exit(EXIT_FAILURE);
            }

           if (WIFEXITED(status)) {
                printf("exited, status=%d\n", WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                printf("killed by signal %d\n", WTERMSIG(status));
            } else if (WIFSTOPPED(status)) {
                printf("stopped by signal %d\n", WSTOPSIG(status));
            } else if (WIFCONTINUED(status)) {
                printf("continued\n");
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
        exit(EXIT_SUCCESS);
    }
}
于 2013-08-05T08:43:24.327 に答える