我正在考虑修改一些代码,我想在linux、unix和OSX上运行。在代码中有一些对sem_init的调用,但是pshared值被设置为零。我读了一些关于unix编程的Rochkind的书,他基本上说,没有共享的sem_init与pthread_mutex_init相同,因为它是在内存中以二进制方式运行的。
问题是--我将这些sem_init更改为pthread_mutex_init,或者使用sem_open获得此代码的更易移植的版本,安全吗?
OSX不支持未命名的信号量,但我想其他两个支持。我真的不想有一个单独的编译标志#ifdef(__APPLE__)
或其他东西。
谢谢
4条答案
按热度按时间ffscu2ro1#
互斥锁和信号量有不同的语义。2互斥锁必须由获取锁的同一线程解锁。3所以锁/解锁必须总是在同一线程中成对出现。
信号量要灵活得多,因为另一个线程可以发布另一个线程使用的令牌。例如,信号量通常用于实现生产者/消费者模式。因此,您必须检查要移植的程序是否符合互斥体的受限语义。
fv2wmkja2#
互斥锁和信号量的语义是不同的。如果非共享信号量仅用作二进制信号量(即,如果其值从不大于1),则它确实等效于互斥锁。但是,这是您需要从代码的逻辑而不是如何初始化来确定的。如果您确定信号量仅用作二进制信号量,那么pthread互斥体是一个完美的替代品。()或编写一个使用pthread互斥体和条件变量模拟信号量的 Package 器。
nr9pn0ug3#
在给定的示例中,切换到互斥体应该是安全的。如果一次只有一个线程可以进入给定的临界区,那么无论互斥体是否被写为信号量您实际上都拥有了互斥体。然而,根据操作系统如何实现函数,您可能会获得不同的性能特征。我不会为此而失眠。但在测试时仍然需要记住一些东西。
uttx8gqw4#
我更喜欢使用互斥锁和condition_variable。
因为在我过去的工作中,我遇到过由于不正确使用信号量而导致的问题,而这些问题极难定位。
但是,很难以绝对正确的方式使用sem_init和sem_post。
如果线程a在线程b之前启动,则线程b可能会永远阻塞在sem_wait上。
很难假定多线程的启动顺序,并且线程a可能会在崩溃时重新启动。
但如果您重复调用pthread_mutex_init,该函数将返回EBUSY https://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_mutex_init.html