我正在编写一个程序来测试进程间通信,特别是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段中有数据并且不是空的。 但是,它会在另一个进程的最后一端捕获信号量,当它清空了sahred内存段并删除了其中的任何数据时。
我在拍摄时遇到了很多麻烦并证实了这一点 a)信号量在每个过程中都是相同的信号量 b)进程1在某个时刻增加信号量,然后捕获相同的信号量并递减它(用sem_getvalue检查)
我通过Oracle VM VirtualBox在Ubuntu虚拟机上运行它。底层笔记本电脑是Microsoft Surfacebook。
已经坚持这个问题48小时,并感到非常沮丧。关于如何更有策略地调试它的任何提示或建议也将不胜感激。
答案 0 :(得分:0)
这没有意义:
sem_post(sem);
sem_wait(sem1);
您递增信号量,然后立即递减它。有一个竞争条件,你的任何一个进程都可以通过等待成功(因为帖子),但由于这个进程已经在CPU上,也许它总是赢。
通常一个进程会发布,另一个进程会等待。然后第一个过程继续进行,如果第二个过程有更多工作需要,可以再次发布。如果这两个进程需要协调它们的操作(即第一个进程暂停直到第二个进程表示它没有问题),那么你将使用第二个信号量,在这个进程上第一个进程总是等待,和第二个职位。因此,一个特定的进程只能在特定的信号量上等待或发布,而不是两者。