【发布时间】:2016-11-11 15:47:16
【问题描述】:
我正在编写一个程序来测试进程间通信,特别是 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 之间获取信号量——此时共享的 mem 段中有数据并且不是空的。 然而,相反,当它清空 sahred 内存段并删除其中的任何数据时,它会在另一个进程的最后捕获信号量。
我做了很多故障排除并确认 a) 信号量在每个进程中是相同的信号量 b) 进程 1 确实会在某个时候增加信号量,然后捕获相同的信号量并减少它(使用 sem_getvalue 进行检查)
我通过 Oracle VM VirtualBox 在 Ubuntu 虚拟机上运行它。底层笔记本电脑是 Microsoft Surfacebook。
在这个问题上卡了 48 小时,感到非常沮丧。任何关于如何更有策略地调试它的提示或建议也将不胜感激。
【问题讨论】: