c - 在哪里放置用于从共享内存段读取和写入的信号量?

标签 c linux pipe shared-memory

我已经实现了一个基于共享内存模拟pipe()系统调用的库。

现在,当我使用任何 fork() 时,代码可以正常工作,例如不调用任何子进程。

我的库需要与任何给定的 int main() 程序一起工作,因此这里的基本问题是应该在库中进行信号量的修改,而不是在 main 程序中。

图书馆:

这是图书馆:

static int flag = FALSE;
static int mutex_init = 0;
static pthread_mutex_t lock;

#define BUFFER 4096
int my_new_finish()
{
    return 1;  // always successful
}


void error_out(const char *msg)
{
    perror(msg);
    exit(EXIT_FAILURE);
}

现在,当我不使用调用 fork()main 程序时,这个库可以正常工作。

但是,当我使用 fork() 时,一切刹车都松了。

例如:

#include <stdio.h>
#include <stdlib.h>
int main()

{
    int spd, pid, rb;
    char buff[4096];
    my_new_init();

    if (my_new_fifo("tmp_shm_pipe",0666) < 0)
    {
        perror("my_new_fifo");
        exit(1);
    }

    if (fork()) 
    {
        spd = my_new_open("tmp_shm_pipe", O_RDONLY, 0600);
        if (spd < 0)
        {
            perror("PARENT: my_new_open");
            exit(1);
        }
        rb = my_new_read(spd, buff, sizeof(buff));
        if (rb > 0)
            write(1, buff, rb);
    }

    else
    {
        spd = my_new_open("tmp_shm_pipe", O_WRONLY, 0600);
        if (spd < 0)
        {
            perror("SON: my_new_open");
            exit(1);
        }
        my_new_write(spd, "hello world!\n", sizeof("hello world!\n"));
    }

    my_new_close(spd);
    my_new_un_link("tmp_shm_pipe");
    my_new_finish();

    return 0;
}

我的问题是:

  1. 如果我不“知道”我将获得的 main() 程序,如何在上述库中使用信号量?

  2. 我尝试将信号量放入库中(而不是放在 main() 程序中),但是 结果不太好。你能解释一下我怎样才能正确地做到这一点吗?

备注:

  1. 请注意,这个main只是一个示例,我可以得到无数其他main程序。

  2. 这是作业

非常感谢

最佳答案

在你的函数my_new_init中,你需要在共享内存中创建一个共享信号音 - 但在它周围有一个保护,以便它只被调用一次;该保护通常位于使用模块静态(或类静态)变量的库模块内部。

sem_t *my_semaphone;
static int init = 0;

int my_new_init()
{
    if (!init)
    {
        my_semaphone = mmap(NULL, sizeof *my_semaphone, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
        if (!sem_init(my_semaphone, 1, 1))
        {
            init = TRUE;
        }
        else
            perror("Sem_init");
    }
    return 1; // always successful
}

然后在顶部的 my_new_read 中:

ssize_t my_new_read(int spd, void *buf, size_t count)
{
    char array[4096];
    memset(array, '\0', 4096);
    ssize_t returnVal = 0;

    sem_wait(my_semaphone);    

并在 my_new_write 中在你写完一些东西后释放信号器。

    sem_post(my_semaphone);
    return returnVal;

上述内容可能需要改进,因为 sem_wait 可能会在数据准备好之前返回,因此在共享内存段的开头使用控制结构可能是明智的。

关于c - 在哪里放置用于从共享内存段读取和写入的信号量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11556132/

相关文章:

c - 关于填充同步结构

c - 如果将字符分配给 C 中的 int 变量会发生什么

c - fork(3) 和 fork(2) 的区别

linux - 符号 -、< 和 > 是什么意思?

swift - 如何在 Swift 中获得 `Pipe` 到标准输入/输出/错误?

c++ - 查找变量声明的简便方法

c - 我如何选择一行来计算c中的矩阵减法

linux - 我应该使用 user_data 还是 Ansible 配置我的 EC2

linux - 为什么perf显示sleep占用所有内核?

Python 子进程管道 block