什么时候应该使用每个线程同步对象? [英] When should each thread synchronization objects be used?

查看:80
本文介绍了什么时候应该使用每个线程同步对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在什么情况下应使用以下每个同步对象?

Under what circumstances should each of the following synchronization objects be used?

  1. ReaderWriter锁定
  2. 信号量
  3. Mutex

推荐答案

  • 由于wait()每次调用post()都会返回一次,因此信号量是基本的生产者-消费者模型-线程间消息的最简单形式,除了可能是信号.使用它们是为了使一个线程可以告诉另一个线程发生了它感兴趣的事情(以及发生了多少次),并用于管理对最多具有固定数量的用户的资源的访问.它们提供了多线程代码所需的排序保证.

    • Since wait() will return once for each time post() is called, semaphores are a basic producer-consumer model - the simplest form of inter-thread message except maybe signals. They are used so one thread can tell another thread that something has happened that it's interested in (and how many times), and for managing access to resources which can have at most a fixed finite number of users. They offer ordering guarantees needed for multi-threaded code.

      互斥体按照他们在罐子上所说的-互斥".它们确保一次仅在线程上保留"访问某些资源的权利.这保证了多线程代码所需的原子性和顺序.在大多数操作系统上,它们还提供了相当复杂的服务员行为,尤其是为了避免优先级倒置.

      Mutexes do what they say on the tin - "mutual exclusion". They ensure that the right to access some resource is "held" by only on thread at a time. This gives guarantees of atomicity and ordering needed for multi-threaded code. On most OSes, they also offer reasonably sophisticated waiter behaviour, in particular to avoid priority inversion.

      请注意,信号量可以轻松地用于实现互斥,但是由于信号量没有所有者线程",因此无法避免信号量的优先级反转.因此,它们并不适合需要锁定"的所有用途.

      Note that a semaphore can easily be used to implement mutual exclusion, but that because a semaphore does not have an "owner thread", you don't get priority inversion avoidance with semaphores. So they are not suitable for all uses which require a "lock".

      • ReaderWriter锁是对互斥锁的一种优化,如果您有很多争用,大多数访问都是只读的,并且允许对受保护的数据结构进行同时读取.在这种情况下,只有在涉及作者的情况下才需要进行排除-读者无需彼此排斥.为了将读者提升为作家,所有其他读者都必须在获得作家锁之前完成(或中止,如果他们也希望成为作家,则开始等待重试).如果不使用ReaderWriter锁,则由于互斥锁会增加簿记功能,因此在锁不快的情况下,锁可能会变慢.

      • ReaderWriter locks are an optimisation over mutexes, in cases where you will have a lot of contention, most accesses are read-only, and simultaneous reads are permissible for the data structure being protected. In such cases, exclusion is required only when a writer is involved - readers don't need to be excluded from each other. To promote a reader to writer all other readers must finish (or abort and start waiting to retry if they also wish to become writers) before the writer lock is acquired. ReaderWriter locks are likely to be slower in cases where they aren't faster, due to the additional book-keeping they do over mutexes.

      条件变量用于允许线程等待某些事实或事实组合为真,其中所讨论的条件比信号量只是被戳"的情况更为复杂,或者没有其他人在使用"它是指互斥锁和读写器锁的写作者部分,或者是没有写者正在使用它"的读写器锁的读者部分.在不同等待线程的触发条件不同但取决于某些或全部相同状态(内存位置或其他任何状态)的情况下,也可以使用它们.

      Condition variables are for allowing threads to wait on certain facts or combinations of facts being true, where the condition in question is more complex than just "it has been poked" as for semaphores, or "nobody else is using it" for mutexes and the writer part of reader-writer locks, or "no writers are using it" for the reader part of reader-writer locks. They are also used where the triggering condition is different for different waiting threads, but depends on some or all of the same state (memory locations or whatever).

      自旋锁用于当您在一个处理器或内核上等待很短时间(例如几个周期),而同时在另一个内核(或硬件,例如I/O总线)上等待时做一些您关心的工作.在某些情况下,它们比其他原语(例如信号量或中断)具有更高的性能,但必须格外小心(因为在现代内存模型中很难使用无锁算法),并且仅在被证明必要时使用(因为有聪明的主意避免使用系统原语)通常是过早的优化.)

      Spin locks are for when you will be waiting a very short period of time (like a few cycles) on one processor or core, while another core (or piece of hardware such as an I/O bus) simultaneously does some work that you care about. In some cases they give a performance enhancement over other primitives such as semaphores or interrupts, but must be used with extreme care (since lock-free algorithms are difficult in modern memory models) and only when proven necessary (since bright ideas to avoid system primitives are often premature optimisation).

      顺便说一句,这些答案不是特定于C#的(因此,例如,有关大多数操作系统"的注释).理查德指出,在C#中,您应该在适当的地方使用普通的旧锁.我相信监视器是一个互斥量/条件变量对,它们被组合成一个对象.

      Btw, these answers aren't C# specific (hence for example the comment about "most OSes"). Richard makes the excellent point that in C# you should be using plain old locks where appropriate. I believe Monitors are a mutex/condition variable pair rolled into one object.

      这篇关于什么时候应该使用每个线程同步对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆