在使用pthread
s的其他线程中,一个线程中的内存写入何时可见时,是否有任何保证?
与Java相比,Java语言规范具有section that specifies the interaction of locks and memory,可以编写可移植的多线程Java代码。
是否有相应的pthreads规范?
当然,你总是可以让共享数据变得不稳定,但这不是我所追求的。
如果这取决于平台,是否有事实上的标准?或者是否应该使用另一个线程库?
答案 0 :(得分:6)
POSIX指定4.11 Memory Synchronization中的内存模型:
应用程序应确保限制多个控制线程(线程或进程)对任何内存位置的访问,以便没有控制线程可以读取或修改内存位置,而另一个控制线程可能正在修改它。使用同步线程执行的函数以及相对于其他线程同步存储器来限制这种访问。以下函数使内存与其他线程同步:
- fork()的
- pthread_barrier_wait()
- 调用pthread_cond_broadcast()
- 调用pthread_cond_signal()
- 那么pthread_cond_timedwait()
- pthread_cond_wait()的
- 在pthread_create()
- 在pthread_join()
- pthread_mutex_lock()的
- pthread_mutex_timedlock()
- pthread_mutex_trylock()
- 调用pthread_mutex_unlock()
- pthread_spin_lock()
- pthread_spin_trylock()
- pthread_spin_unlock()
- pthread_rwlock_rdlock()
- pthread_rwlock_timedrdlock()
- pthread_rwlock_timedwrlock()
- pthread_rwlock_tryrdlock()
- pthread_rwlock_trywrlock()
- pthread_rwlock_unlock()
- pthread_rwlock_wrlock()
- sem_post()
- sem_timedwait()
- sem_trywait()在
- sem_wait()
- 了semctl()
- 执行semop()
- 等待()
- waitpid函数()
pthread_once()函数应为给定pthread_once_t对象的每个线程中的第一个调用同步内存。
如果互斥锁类型为PTHREAD_MUTEX_RECURSIVE且调用线程已拥有互斥锁,则pthread_mutex_lock()函数无需同步内存。如果互斥锁类型为PTHREAD_MUTEX_RECURSIVE且互斥锁的锁定计数大于1,则pthread_mutex_unlock()函数无需同步内存。
除非另有明确说明,否则如果上述函数之一返回错误,则无法指定调用是否导致内存同步。
应用程序可能允许多个控制线程同时读取内存位置。
答案 1 :(得分:0)
我不知道POSIX线程提供了这样的保证。它们没有用于对线程共享对象进行原子访问的模型。如果它适用于POSIX线程,那么您可以使用某种锁定的唯一保证。
Modern C,C11,(可能还有C ++ 11)有这种问题的模型。它有线程和原子(围栏和所有东西),当你可以假设一个线程完成的修改被另一个线程看到时,它会为你提供准确的规则。
C11的线程接口是POSIX线程的熟化版本,功能较少。不幸的是,该线程接口的语义规范还有很多不足之处,基本上很多地方都缺少语义。但是C11接口和POSIX线程语义的结合可以让您很好地了解现代系统中的工作原理。
编辑:因此,如果您希望保证内存同步,请使用POSIX提供的锁定接口或进行原子操作。所有现代编译器都有扩展,提供这些,gcc和系列(icc,opencc,clang)具有例如__sync...
内置系列。它最新版本也支持新的C11 _Atomic
功能。还有一些包装器可以为接近_Atomic
的其他编译器提供接口。