信号量对象没有所有者,你明白了吗?

开发 前端
既然提到了所谓的高性能版本,我想原作者所表达的意思是:对于尔等 C++ 工人来说,平常使用无妨,但是如果是性能攸关的代码,频繁地切换内核上下文所带来的性能开销,不可小视。

相较于互斥对象(Mutex)和临界区对象(Critical Section) ,信号量没有所有者,它们只有计数。

ReleaseSemaphore 函数将会以指定的数量增加对应信号量对象的计数。 (增加计数这个动作,可能会释放正在等待的线程)但是释放信号量的线程不必与最初声明它的线程相同。这与互斥对象和临界区对象不同,后者要求声明线程也是释放线程。

有些人以类似互斥对象的方式使用信号量: 他们创建一个初始计数为 1 的信号量,并像这样使用它,如下面代码所示:

WaitForSingleObject(hSemaphore, INFINITE);
… do stuff ..
ReleaseSemaphore(hSemaphore, 1, NULL);

如果线程在设法释放信号量之前退出(或崩溃),则信号量计数器不会自动还原。相较于互斥对象,如果所有者线程在持有互斥对象时终止,则释放互斥对象。因此,对于这种使用模式,使用互斥对象更加合适一些。

如果资源的概念所有权可以跨线程,则信号量非常有用。我们来看下图:

此技巧不适用于互斥对象或临界区对象,因为互斥对象和临界区对象具有所有者,并且只有所有者才能释放互斥对象或临界区对象。

请注意,如果 KeepWorking 函数退出并忘记释放信号量,则计数器不会自动恢复。操作系统不知道信号量”属于”该工作项。

信号量的另一种常见用法模式与资源保护模式相反:它是资源生成模式。在此模型中,信号量计数通常为零,但在有工作要完成时递增。

请注意,在这种情况下,甚至没有信号量的概念”所有者”,除非你将工作项本身(位于工作列表数据结构上的某处)视为所有者。如果 ProcessWork 线程退出,则不希望自动释放信号量,那会破坏掉内部计数。在这种情况下,信号量是合适的对象。

(生产者/使用者信号量的更高性能版本是 I/O 完成端口。)

总结

既然提到了所谓的高性能版本,我想原作者所表达的意思是:对于尔等 C++ 工人来说,平常使用无妨,但是如果是性能攸关的代码,频繁地切换内核上下文所带来的性能开销,不可小视。

责任编辑:武晓燕 来源: 今日头条
相关推荐

2023-06-02 08:14:58

信号量对象线程

2021-04-13 09:20:15

鸿蒙HarmonyOS应用开发

2010-04-21 16:50:31

Unix信号量

2020-11-05 09:59:24

Linux内核信号量

2010-04-21 16:42:48

Unix信号量

2021-09-07 07:53:42

Semaphore 信号量源码

2010-04-21 16:25:13

Unix信号量

2020-09-25 07:34:40

Linux系统编程信号量

2010-04-21 15:37:38

Unix信号量

2024-10-29 15:23:45

Python线程安全

2019-11-19 09:00:38

JavaAND信号量

2010-04-21 17:10:25

Unix信号量

2010-07-15 15:32:10

Perl线程

2010-03-17 16:36:10

Java信号量模型

2009-12-08 12:14:43

2022-12-30 08:35:00

2016-11-23 16:08:24

Python处理器分布式系统

2017-05-11 14:05:25

Consul分布式信号量

2021-02-03 20:10:29

Linux信号量shell

2010-03-16 17:52:27

Java多线程信号量
点赞
收藏

51CTO技术栈公众号