2

我已经实现了一个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);
}

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

但是,当我使用时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. 这是作业

非常感激

4

2 回答 2

2

好的,我会尽力而为,因为我不知道您对整个概念有多熟悉。

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

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

这是一个 pdf,带有一个很好的英文注释代码示例,用于创建、使用和销毁信号量,并带有一个示例 main。它的标题是德文的,但里面没有其他不是 C 或英文的。

我希望它对您的技能有所帮助并且不会太“低级”^^

于 2012-07-19T08:04:45.113 回答
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 可能会在数据准备好之前返回,因此在共享内存段的开头使用控制结构可能是明智的。

于 2012-07-19T08:19:52.403 回答