我已经实现了一个模拟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()
我的问题是:
如何在上面的库中使用信号量,我不会“知道”我将被提供的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;
}
程序中)但是
它没有成功。你能解释我怎么能正确地做到这一点?
备注:
请注意,此main()
只是一个示例,我可以获得无数其他main()
计划。
这是作业
非常感谢
答案 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可能会在数据准备好之前返回,因此在共享内存段的开头使用控制结构可能是明智的。