PTHREAD 互斥锁是只避免同时访问资源,还是做更多的事情?
Posted
技术标签:
【中文标题】PTHREAD 互斥锁是只避免同时访问资源,还是做更多的事情?【英文标题】:Does a PTHREAD mutex only avoid simultaneous access to a resource, or it does anything more? 【发布时间】:2017-07-30 22:37:16 【问题描述】:示例: 线程完成对共享变量的写入,然后解锁它,但继续使用该变量的值(不更改它)。 立即,另一个线程成功解锁()该互斥体并读取共享变量。
根据我的(错误)理解,在这种情况下可能会发生一些事情:
在 WRITER 线程上:
编译器优化可以使写入仅在以后发生
写入的值可以保留在当前 CPU 内核的缓存中,并在稍后刷新到内存中
在 READER 线程上:
变量的值可能在互斥锁()之前已经被读取,并且由于一些编译器优化或者只是CPU缓存的正常工作,仍然被认为是“已经从内存中读取”,因此,不再从内存中取出。
因此,我们这里的值不是来自另一个线程的更新值。
pthread mutex lock/unlock() 函数是否执行任何代码以将当前缓存“刷新”到内存以及确保当前线程与其他所有内容同步所需的任何其他内容(除了缓存),还是只是不需要(至少在所有已知架构中)?
因为如果所有互斥锁的作用与名称一样——互斥它的引用——那么,如果我有数千个线程处理相同的数据,并且从我的算法的角度来看,我已经知道当一个线程正在使用一个变量,没有其他线程会同时尝试使用它,这意味着我不需要互斥锁?或者我的代码是否会缺少一些在 PTHREAD 库中实现的低级和特定于体系结构的方法以避免上述问题?
【问题讨论】:
【参考方案1】:pthreads 互斥锁和解锁函数在 POSIX 中的函数列表中“...同步线程执行并相对于其他线程同步内存”。所以是的,它们不仅仅是联锁执行。
他们是否需要向硬件发出额外的指令当然取决于架构(注意几乎每个现代 CPU 架构都会至少愉快地重新排序读取,除非另有说明) ,但在任何情况下,这些函数都必须充当“编译器屏障”——也就是说,它们确保编译器不会在原本允许的情况下重新排序、合并或忽略内存访问。
允许多个线程读取共享值而不会相互排斥 - 您需要确保写入和读取线程都在写入和读取之间执行一些同步功能。例如,允许的情况是有许多读取线程延迟读取共享状态,直到它们通过障碍 (pthread_barrier_wait()
) 和一个写入线程执行其对共享状态的所有写入之前它通过了障碍。读写锁 (pthread_rwlock_*
) 也是围绕这个想法构建的。
【讨论】:
以上是关于PTHREAD 互斥锁是只避免同时访问资源,还是做更多的事情?的主要内容,如果未能解决你的问题,请参考以下文章