2012-07-19 57 views
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. 这是功课

非常感谢

回答

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返回前的数据准备好,因此它可能是明智的你的共享内存段的开始使用控制结构上面可能需要改进。

+0

我想你的建议,但是'HELLO-world'在'main'仍然没有显示在控制台(意为标准输出)。请参阅修改后的帖子 – ron 2012-07-19 08:56:29

+0

这将不会在fork()时共享互斥锁。 – nos 2012-07-19 09:04:31

+0

@nos:任何方式呢?我怎样才能使用'fork()'工作?谢谢 – ron 2012-07-19 09:08:35

2

好吧,我会尽我所能,因为我不知道你是多么熟悉的整个概念。 1)信号量最可能“正确”的地方在于读写功能。 要同步memorysegment上的进程,您必须将信号量也放在共享内存中。 (为了使它们accessable到所有进程)

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

这与创建,使用和销毁信号量,与样品主的好,英语评论codeexample的PDF文件。它的标题是德语,但没有其他地方没有C或英语。

我希望它能帮助,是不是太“低层次的”为你的技能^^