Многопоточность C#: Получить необходимую блокировку чтения?

Мне 21 год и начал использовать Emacs в 15, только переехав для Textmate/E в последние годы. Я лично не могу выдержать IDE, чувствуя, что они мешают намного больше, чем они помогают. Дайте мне хороший прямой текстовый редактор любой день.

43
задан André Hauptfleisch 3 November 2009 в 17:03
поделиться

12 ответов

The short answer is: it depends.

The long answer is:

  • If it is not a shared value, i.e, only one thread can see it (or use it), you don't need any synchronization.

  • If it is an immutable value, i.e., you set it only once and then only ever read, it is safe to do so without synchronization (as long as you don't start reading before the first write completes).

  • If it is a "primitive" type of at most 32-bits (e.g. byte, short, int) you can get stale (old) data when reading. If that doesn't bother you, you're set. If stale data is undesirable, making the variable volatile can fix this problem without additional synchronization for reads. But if you have racing writers, you will need to follow the same advice as for longs below.

  • If it is a "primitive" type longer than 32-bits (e.g. long, decimal, double) you need synchronization, otherwise you could read "half" of one value, "half" of another, and get crazy results. For this the recommended approach is to use the methods in the Interlocked class, for both reads and writes..

  • If it is a reference type, you will need synchronization to avoid seeing an invalid state (Jeff Lamb's picture example is a good one). The lock statement might be enough for that. Again, you need to lock for both reads and writes.

There are some other points to consider (how long to lock, for example), but I think these are enough to answer your question.

94
ответ дан 26 November 2019 в 22:31
поделиться

In adition to the answers below you can also do a read lock using the ReadWriterLockSlim.

That would allow you to do only a read lock when reading and a write lock when modifying your variable. Multiple threads can have a read lock at the same time but as soon as a thread requests a write lock all new request are blocked until it is complete.

This sort of locking would be usefull if you are doing alot of reads and not many writes.

As with most multithreading issues, research it enough to understand if it really fits your problem the ReadWriterLock would not be suitable for every locking situation.

5
ответ дан 26 November 2019 в 22:31
поделиться

It depends on the type of variable and your platform. For example, reading Int64s is not guaranteed to be atomic on 32 bit machines. Hence, Interlocked.Read.

11
ответ дан 26 November 2019 в 22:31
поделиться

If the loading of the value is done in 1 assembly instruction, it's not necessary to get a lock. You don't care if the value changed 10 minutes ago or 1 microsecond ago. You just want the value now.

However, if you're loading a HUGE array or picture or something, it'd probably be a good idea to lock it out. In theory, you can get preempted while loading the data and have half of the first item and half of the second item.

If it's a simple variable, though, like a bool or int, it's not necessary.

5
ответ дан 26 November 2019 в 22:31
поделиться

Это зависит от того, является ли это локальной или общей переменной, и может ли что-то еще записать в нее в тем временем, и что вы собираетесь делать после его прочтения.

Если вы принимаете решение на основе переменной, учтите, что следующая строка кода может быть основана на данных, которые теперь устарели.

3
ответ дан 26 November 2019 в 22:31
поделиться

Чтение не требует блокировки; до тех пор, пока вы не заботитесь о «правильности» чтения. Это опасно, только если вы пытаетесь писать без блокировки.

3
ответ дан 26 November 2019 в 22:31
поделиться

Если это константа, нет.

Если это обновляемое значение, да, если вам нужна согласованность.

Для обновляемых значений, где необходимо управлять точным значением, тогда да, вы должны использовать блокировку или другой метод синхронизации для чтения и записи; и, возможно, блокировать в течение всего объема, в котором используется значение.

2
ответ дан 26 November 2019 в 22:31
поделиться

Answer is it depends. If the value of the variable does not change when the threads are accessing the variable. otherwise, its needed.

Also, You can use Interlocked.XXX series for maintaining atomicity in reading\writing the variable .

2
ответ дан 26 November 2019 в 22:31
поделиться

It is 100% necessary unless you are 100% sure that the variable's value won't change while the reader threads are running.

1
ответ дан 26 November 2019 в 22:31
поделиться

Нужно? Нет.

... но если возможно, что другой поток может попытаться записать в него во время чтения (например, коллекция и т. Д.), Тогда это может быть хорошей идеей.

1
ответ дан 26 November 2019 в 22:31
поделиться

Пока он не меняется во время выполнения других потоков, вам не нужно его блокировать. В случае изменения вы должны его использовать.

0
ответ дан 26 November 2019 в 22:31
поделиться

Если переменная никогда не записывается кем-то (по крайней мере, время, когда он доступен), вам не нужно блокировать его, потому что нет возможности пропустить обновления. То же самое происходит, если вы не заботитесь о пропущенных обновлениях (то есть это не проблема, если вы получите более старое значение). В противном случае вам следует использовать какую-то синхронизацию

0
ответ дан 26 November 2019 в 22:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: