我正在编写一个程序来测试进程间通信,特别是POSIX共享内存。我使用POSIX信号量来同步进程对共享内存的访问。 (我读过posix sem_open函数让你可以在进程之间使用相同的信号量,只要你使用相同的“名称”标识符。)信号量被一个进程占用
问题是 - 当我做sem_wait和sem_post一个进程...另一个进程不捕获信号量。过程1只是占据信号量并释放信号,然后自己抓住信号而不会让另一个过程有机会介入。
这里是一个过程1
if ((sem1 = sem_open(request->mem_group.sem_name, O_CREAT, 0644, 0)) ==
SEM_FAILED) {
perror("sem_open");
goto finish;
}
cache = simplecache_get(request->file_path);
*(int *)mem_shared = cache == -1 ? -1 : 1;
sem_post(sem);
sem_wait(sem);
if (cache == -1) {
break;
fprintf(stdout, "File was not found, going to finish\n");
}
file_length = lseek(cache, 0, SEEK_END);
lseek(cache, 0, SEEK_SET);
*(size_t *)mem_shared = file_length;
sem_post(sem);
sem_wait(sem1);
if (!file_len) {
goto finish;
}
bytes_transferred = 0;
while (bytes_transferred < file_len) {
//rest of while loop here which transfers file
代码这里是在过程2的代码块,它应该被抓住的信号,但不
sem_wait(sem1);
file_size = *(size_t *)mem_shared;
gfs_sendheader(ctx, GF_OK, file_size);
sem_post(sem1);
if (!file_size) {
fprintf(stderr, "File is empty. Go to finish");
break;
}
这样的想法是 - 这个过程2应该是在另一个过程中的post/wait之间获取seemaphore--在这一点上共享的mem段有数据并且不是空的。然而,相反,它在其他进程的最后一端捕获信号量,此时它清空了内存段并删除了内部的任何数据。
我做了很多的麻烦拍摄的,并证实 A)的信号是在每个进程 B中的相同信号)顺序1确实在某一时刻的增量信号,再搭上同一个信号和递减它(选中这与sem_getvalue)
我是一个Ubuntu的虚拟机上通过的Oracle VM VirtualBox运行此。底层笔记本电脑是微软Surfacebook。
一直停留在这个问题上48小时,感到非常沮丧。任何有关如何更具战略性地调试它的技巧或建议也将不胜感激。
非常感谢你gilez。你是对的,我想我可以像互斥体一样使用它,并且如果另一个进程在sem_wait中,那么它应该是第一个在线。 感谢您一个非常有用的答案 – rafiya
@raf,你不能做任何假设哪些进程(或线程)将获得当您发布去。简单地看,我找不到参考,但如果你没有这样的假设编码,你会安全的:-) – gilez