信号量通过一个过程占据

时间:2016-11-11 15:47:16

标签: c posix ipc semaphore

我正在编写一个程序来测试进程间通信,特别是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小时,并感到非常沮丧。关于如何更有策略地调试它的任何提示或建议也将不胜感激。

1 个答案:

答案 0 :(得分:0)

这没有意义:

sem_post(sem);
sem_wait(sem1);

您递增信号量,然后立即递减它。有一个竞争条件,你的任何一个进程都可以通过等待成功(因为帖子),但由于这个进程已经在CPU上,也许它总是赢。

通常一个进程会发布,另一个进程会等待。然后第一个过程继续进行,如果第二个过程有更多工作需要,可以再次发布。如果这两个进程需要协调它们的操作(即第一个进程暂停直到第二个进程表示它没有问题),那么你将使用第二个信号量,在这个进程上第一个进程总是等待,和第二个职位。因此,一个特定的进程只能在特定的信号量上等待或发布,而不是两者。