如何使用流程实现生产者-消费者? [英] How to implement producer-consumer using processes?

查看:50
本文介绍了如何使用流程实现生产者-消费者?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 1 个父进程和 1 个子进程来实现生产者-消费者应用程序.该程序应该像这样工作:

I'm trying to implement a producer-consumer application using 1 parent process and 1 child process. The program should work like this:

1 - 父进程是生产者,子进程是消费者.
2 - 生产者创建一个文件,消费者删除该文件.
3 - 创建文件后,父进程向子进程发送 SIGUSR1 信号,子进程然后删除文件并向父进程发送 SIGUSR2 信号,表示可以再次创建文件.

1 - The parent process is the producer and the child process is the consumer.
2 - The producer creates a file, the consumer removes the file.
3 - After the file has been created, the parent process sends a SIGUSR1 signal to the child process which then removes the file and sends a SIGUSR2 signal to the parent, signaling it that the file can be created again.

我已经尝试实现这个问题,但我一直收到这个错误:

I've tried implementing this problem but I keep getting this error:

User defined signal 1: 30.   

我真的不明白可能是什么问题.我刚刚开始学习过程和信号,也许我错过了一些东西.任何帮助,将不胜感激.这是我的实现:

I don't really understand what could be the problem. I've just started learning about process and signals and maybe I'm missing something. Any help would be appreciated. Here's my implementation:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

pid_t child, parent;

void producer()
{
    system("touch file");
    printf("File was created.\n");
}

void consumer()
{
    system("rm file");
    printf("File was deleted.\n");
    kill(parent, SIGUSR2); // signal -> file can created by parent
}

int main(void)
{
    system("touch file");

    pid_t pid = fork();

    for(int i = 0; i < 10; ++i)
    {
        if(pid < 0) // error fork()
        {
            perror("fork()");
            return -1;
        }
        else if(pid == 0) // child proces - consumer
        {
                child = getpid();
                signal(SIGUSR1, consumer);
                pause();
        }
        else // parent process - producer
        {
                parent = getpid();
                signal(SIGUSR2, producer);
                // signal -> file can be deleted by child
                kill(child, SIGUSR1); 
        }
    }

    return 0;
}

我忘了提到一次只能有一个文件.

I forgot to mention that there can only be one file at a time.

推荐答案

经过大量研究和阅读所有建议后,我终于设法使程序运行.这是我的实现.如果您发现任何错误,或者本可以做得更好,请随时更正我的代码.我愿意接受建议.

After a lot of research and reading all of the suggestions I finally managed to make the program work. Here is my implementation. If you see any mistakes or perhaps something could have been done better, then feel free to correct my code. I'm open to suggestions.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void signal_handler(int signal_number)
{
    sigset_t mask;

    if(sigemptyset(&mask) == -1 || sigfillset(&mask) == -1)
    {// initialize signal set || block all signals
        perror("Failed to initialize the signal mask.");
        return;
    }

    switch(signal_number)
    {
        case SIGUSR1:
        {
            if(sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
            { // entering critical zone
                perror("sigprocmask(1)");
                return;
            } //---------------------

            sleep(1);
            system("rm file");          /* critical zone */
            puts("File was removed.");

              //--------------------
            if(sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
            {// exiting critical zone
                perror("1 : sigprocmask()");
                return;
            }

            break;
        }
        case SIGUSR2:
        {

            if(sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
            {// entering critical zone
                perror("2 : sigprocmask()");
                return;
            } //---------------------

            sleep(1);
            system("touch file");
            puts("File was created.");  /* critical zone */


              // --------------------
            if(sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
            {// exiting critical zone
                perror("sigprocmask(2)");
                return;
            }

            break;
        }
    }
}

int main(void)
{
    pid_t pid = fork();

    struct sigaction sa;
    sa.sa_handler = &signal_handler; // handler function
    sa.sa_flags = SA_RESTART;

    sigaction(SIGUSR1, &sa, NULL);
    sigaction(SIGUSR2, &sa, NULL);

    if(pid < 0)
    {
        perror("fork()");
        return -1;
    }

    for(int i = 0; i < 10; ++i)
    {
        if(pid > 0) // parent - producer
        {
            sleep(2);
            // signal -> file was created
            kill(pid, SIGUSR1);
            pause();
        }
        else // child - consumer
        {
            pause();
            // signal -> file was removed
            kill(getppid(), SIGUSR2);
        }
    }

    return 0;
}

这篇关于如何使用流程实现生产者-消费者?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆