多线程概念和C#中的锁定 [英] Multi-threading concept and lock in c#

查看:69
本文介绍了多线程概念和C#中的锁定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到有关锁的信息,尽管一点也不了解.我的问题是为什么我们要使用未使用的 object 并将其锁定,以及这如何使某些线程安全或如何在多线程中发挥作用?没有其他方法可以制作线程安全的代码.

I read about lock, though not understood nothing at all. My question is why do we use a un-used object and lock that and how this makes something thread-safe or how this helps in multi-threading ? Isn't there other way to make thread-safe code.

public class test {
    private object Lock { get; set; }

    ...
    lock (this.Lock) { ... }
    ...
}

对不起,我的问题很愚蠢,但是我听不懂,尽管我已经使用了很多次.

Sorry is my question is very stupid, but i don't understand, although i've used it many times.

推荐答案

在一个线程正在修改另一个线程的情况下从一个线程访问一段数据称为数据竞争条件"(或简称为数据竞争"),并且可能导致数据损坏.(*)

Accessing a piece of data from one thread while other thread is modifying it is called "data race condition" (or just "data race") and can lead to corruption of data. (*)

锁只是避免数据争用的一种机制.如果两个(或多个)并发线程锁定了相同的锁定对象,则在锁定期间,它们不再并发并且不再导致数据争用.本质上,我们正在序列化访问共享数据.

Locks are simply a mechanism for avoiding data races. If two (or more) concurrent threads lock the same lock object, then they are no longer concurrent and can no longer cause data races, for the duration of the lock. Essentially, we are serializing the access to shared data.

诀窍是将锁保持在所需的宽"范围内,以避免数据争用,尽可能保持在窄"的范围内,以通过并发执行来提高性能.这是一个很好的平衡点,可以很容易地从任一方向克服,这就是为什么多线程编程很困难.

The trick is to keep your locks as "wide" as you must to avoid data races, yet as "narrow" as you can to gain performance through concurrent execution. This is a fine balance that can easily go out of whack in either direction, which is why multi-threaded programming is hard.

一些准则:

  • 只要所有线程都在读取数据,而且任何线程都不会对其进行修改,则不需要锁.
  • 相反,如果至少有一个线程可能在某个时刻修改数据,则访问同一数据的所有所有并发代码路径必须通过锁正确地序列化,即使那些仅读取数据的锁也是如此.
    • 在一个代码路径中使用锁而不在另一个代码路径中使用锁将使数据在竞争条件下保持开放状态.
    • 此外,在一个代码路径中使用一个锁定对象,而在另一(并发)代码路径中使用不同锁定对象不会序列化这些代码路径,从而使您对数据竞赛敞开大门.
    • li>
    • 另一方面,如果两个并发代码路径访问不同的数据,则它们可以使用不同的锁对象.但是,只要有多个锁定对象,就当心死锁.死锁通常也是代码竞争条件"(还有heisenbug,请参见下文).
    • As long all threads are just reading the data and none will ever modify it, lock is unnecessary.
    • Conversely, if at least one thread might at some point modify the data, then all concurrent code paths accessing that same data must be properly serialized through locks, even those that only read the data.
      • Using a lock in one code path but not the other will leave the data wide open to race conditions.
      • Also, using one lock object in one code path, but a different lock object in another (concurrent) code path does not serialize these code paths and leaves you wide open to data races.
      • On the other hand, if two concurrent code paths access different data, they can use different lock objects. But, whenever there is more than one lock object, watch out for deadlocks. A deadlock is often also a "code race condition" (and a heisenbug, see below).

      (*)之所以称为种族",是因为并发线程正在竞相"对共享数据执行操作,而赢得比赛的人将决定操作的结果.因此,结果取决于执行的定时,这在现代抢先式多任务操作系统上基本上是随机的.更糟糕的是,可以通过调试器之类的工具观察程序执行,从而轻松地更改时间,这使它们"heisenbugs" (即观察到的现象仅通过观察行为即可改变).

      (*) It is called "race" because concurrent threads are "racing" towards performing an operation on the shared data and whoever wins that race determines the outcome of the operation. So the outcome depends on timing of the execution, which is essentially random on modern preemptive multitasking OSes. Worse yet, timing is easily modified by a simple act of observing the program execution through tools such as debugger, which makes them "heisenbugs" (i.e. the phenomenon being observed is changed by the mere act of observation).

      这篇关于多线程概念和C#中的锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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