当前位置: 首页 > 知识库问答 >
问题:

使用POSIX计数信号量作为二进制信号量

尚景焕
2023-03-14
sem = sem_open(argv[optind], flags, perms, 1); // Initialising semaphore to 1

    while(sem_getvalue(sem) > 0)
    {
    continue;

    }
    sem_post(sem);

我有多个进程与Sempahore同步。我知道这段代码不允许gurantee出现这样的情况:在sem_getvalue期间,即使sem值变为零,甚至在调用特定进程中的sem_post之前,anotehr进程也可能调用sem_post,使值变为2。如何解决这种情况。

我的问题不能通过互斥体来解决,在我的问题中,有些进程只用于信号,即sem_post操作,而在互斥体中,所有进程都将等待并不断地发出信号

共有1个答案

闻人宜
2023-03-14

您发布的代码有一些问题。

while(sem_getvalue(sem) > 0)

这被称为忙等待,这意味着进程在信号量上旋转,不会将CPU让给调度器。通常,繁忙等待仅在等待应该小于上下文切换时间(例如,低延迟)的场景中进行。

下一个问题是你的语义颠倒了。当信号量大于0时,则递减并继续。此外,您的调用不是原子的,这会引入许多争用条件。

const char* lock_file = ".lock";

const int fd_lock = open(lock_file, O_CREAT);

flock(fd_lock, LOCK_EX);

// do stuff

flock(fd_lock, LOCK_UN);

// do more stuff

close(fd_lock);    
unlink(lock_file);
 类似资料:
  • 问题内容: 我一直在尝试了解可重入锁和信号量(可重入锁的嵌套与释放/解锁机制)。 似乎拥有信号量需要您编写一个经过更彻底测试的应用程序,因为release()方法不会检查释放许可的线程是否实际上持有它。测试我的测试代码时,我发现这可能会随后使许可数量超出初始限制。另一方面,如果线程在调用unlock方法时未持有可重入锁,则将收到IllegalMonitorException。 因此,可以说没有真正

  • 在计算信号量时,没有提供相互排斥,因为有一组同时需要在临界区执行的进程。 然而,二进制信号严格提供互斥。 在这里,临界区域不能有超过1个槽位,而临界区域最多只能有1个槽位。 信号量只能有两个值,0或1。 下面,我们来看看二进制信号量的编程实现。

  • 与二值信号量可以类比成只能保存一个数据的队列一样,计数信号量可以类比成长度大于1的队列,用户在使用的时候同样不关注队列中的数据,只关心这个队列是不是非空的。 计数信号量的主要用在两个方面: 计数事件 事件每次发生时,都会增加计数信号量的值,而任务在每次处理完后都会将计数信号量的值减少。因此,计数值其实代表着已经发生的事件次数和已经处理完的事件次数只差,也因此,计数信号量的初始值设置成0是合理的。

  • 我有: 产生项目的许多线程 要点: 生成项目比更新GUI快得多 我们可能有很多新项目同时生产 每个项目生产后都必须进行一次GUI更新 如果产品同时发生,所有产品必须只进行一次更新...没有必要多次刷新GUI 我想我正在寻找一些实现二进制信号量的标准结构,其中最大许可数是1,这样工作人员就可以调用多个,而不会相互阻塞,如果调用了一个,那么: 如果GUI线程正在睡眠= 代码应如下所示: 请注意,使用1

  • 头文件 semaphore.h sys/stat.h fcntl.h 常用函数 函数 说明 [[sem_open sem_open]] 打开一个有名信号量 [[sem_close sem_close]] 关闭一个信号量 [[sem_unlink sem_unlink]] 删除一个信号量 [[sem_post sem_post]] 【V操作】释放操作:信号量的值加1 [[sem_wait sem_w

  •  提示: 任务通知在某些情况下可以提供一个轻量的选择用以替代二值信号量,详见:任务通知  二值信号量(Binary Semaphores)通常用来实现互斥、同步。二值信号量与互斥量虽然相似,但是互斥量拥有优先级继承的特性,而二值信号量没有。这使得二值信号量更加合适去实现同步,互斥量更加适合去实现互斥。 信号量可以设置阻塞时间,当任务试图获取一个暂时不可用的信号量的适时候,会进入阻塞态,直到阻塞时间