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 函数时处于子进程中。

另一个 pid 是子进程的 pid,它允许原始线程等待子进程完成。如果您希望在进程之间传递数据,请考虑使用管道。popen 调用返回两个文件描述符,一个用于写入端,另一个用于读取端。在 fork 和两个进程可以通信之前设置它。

于 2013-08-05T08:52:17.427 回答
1

wait使父进程在继续之前等待任何子进程终止(最好用于waitpid等待某个子进程),而sleep一旦参数通过的时间结束,则使进程进入睡眠状态并恢复它。
这两个调用都会使进程阻塞
而且也不是说孩子马上就跑,这是不确定的行为

如果要在生产者和消费者之间传递数据,请使用管道或 *NIX 套接字,或者exit如果单个整数就足够了,则使用来自子节点的返回值。

man 等,用宏就可以得到孩子的返回值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 回答