4

我正在考虑更改一些我想在 linux、unix 和 OSX 上运行的代码。代码中有一些对 sem_init 的调用,但 pshared 值设置为零。我在 Rochkind 关于 unix 编程的书中做了一些阅读,他基本上说不共享的 sem_init 与 pthread_mutex_init 相同,因为它以内存中的二进制方式运行。

问题是 - 我是否可以安全地将这些 sem_init 更改为 pthread_mutex_init,或者使用 sem_open 来获得此代码的更便携版本?

OSX 不支持未命名的信号量,但我猜其他两个支持。我真的不想有一个单独的编译标志#ifdef(__APPLE__)或其他东西。

谢谢

4

3 回答 3

10

互斥量和信号量具有不同的语义。互斥锁必须由获得锁的同一线程解锁。所以锁定/解锁必须总是成对出现在同一个线程中。

信号量要灵活得多,因为另一个线程可以发布另一个线程使用的令牌。例如,它们通常用于实现生产者/消费者模式。因此,您必须检查要移植的程序是否符合互斥锁的受限语义。

于 2012-07-25T22:36:48.893 回答
2

互斥锁和信号量的语义不同。确实,如果非共享信号量仅用作二进制信号量,即如果它的值永远不会大于 1,则它等同于互斥锁。但是,这是您需要从代码的逻辑中确定的东西,而不是它如何被初始化。如果您确定信号量仅用作二进制信号量,那么 pthread 互斥锁是完美的替代品。如果没有,您可以使用 sem_open() 来实现可移植性,或者编写一个包装器,使用 pthread 互斥锁和条件变量来模拟信号量。

于 2012-07-25T21:52:50.443 回答
1

在给定的实例中切换到互斥锁应该是安全的。如果一次只有一个线程可以进入给定的临界区,那么无论是否编写为信号量,您都有效地拥有了一个互斥锁。但是,根据操作系统实现功能的方式,您可能会获得不同的性能特征。这不是我会失眠的事情,但仍然是在测试时要记住的事情。

于 2012-07-25T21:45:00.817 回答