在哪里放置信号量阅读&从共享内存段写?

时间:2012-07-19 07:45:45

标签: c linux pipe shared-memory

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

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

我的库需要在任何给定的 int main()程序中使用,因此这里的基本问题是使用信号量的修改应该在库中进行,而不是在{ {1}}计划。

图书馆:

这是图书馆:

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); } 的{​​{1}}程序时,这个库工作正常。

但是,当我使用main时,所有地狱都会松动。

例如:

fork()

我的问题是:

  1. 如何在上面的库中使用信号量,我不会“知道”我将被提供的fork()程序?

  2. 我试图将信号量放入库中(不在#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; } 程序中)但是 它没有成功。你能解释我怎么能正确地做到这一点?

  3. 备注:

    1. 请注意,此main()只是一个示例,我可以获得无数其他main()计划。

    2. 这是作业

    3. 非常感谢

2 个答案:

答案 0 :(得分:2)

好的,我会尽我所能,因为我不知道你对整个概念的熟悉程度。

1)信号量最可靠的“正确”位置是读写功能。 要同步内存段上的进程,您还必须将信号量放在共享内存中。 (为了使它们可以访问所有进程)

http://pdfcast.org/download/semaphores-sharedmem.pdf

这是一个pdf,带有一个良好的,英语注释的代码示例,用于创建,使用和销毁信号量,以及样本main。它的标题是德语,但没有别的东西不是C或英语。

我希望它对你的技能有帮助并且不会“低水平”^^

答案 1 :(得分:2)

在你的函数my_new_init中,你需要在共享内存中创建一个共享的semaphone - 但要保护它,以便只调用一次;这个防护通常使用模块静态(或类静态)变量在库模块内部。

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发布了一些内容之后发布了semaphone。

    sem_post(my_semaphone);
    return returnVal;

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