Почему “блокировка (typeof (MyType))” проблема?

Модуль fdesc может быть полезен для асинхронного общения с сокетом или каналом, но когда ему дается fd, который ссылается на обычный файл файловой системы, он блокирует io (и при этом через довольно странный интерфейс). Для диска io fdesc - это змеиное масло; не используйте его.

По состоянию на май 2017 года единственный разумный способ получить асинхронный диск io в витой форме - это обернуть синхронные вызовы io в deferToThread.

45
задан Community 23 May 2017 в 12:34
поделиться

4 ответа

Это опасно, потому что что угодно может взять эту блокировку, поэтому трудно или невозможно предотвратить ситуацию взаимоблокировки .

Раньше на эту тему была статья («Не блокируйте типы объектов!», Статья доктора GUI) с некоторыми комментариями Рико Мариани. Очевидно, статья больше не доступна напрямую, но вокруг плавают "зеркала", в том числе на http://bytes.com/topic/c-sharp/answers/249277-dont-lock-type-objects .

Вот выдержка:

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

Но подождите; это даже хуже, чем все это. Как оказалось, в текущих версиях среды выполнения .NET объекты типов иногда используются совместно между доменами приложений (но не между процессами). (Обычно это нормально, поскольку они неизменяемы.) Это означает, что это ' Возможно, ДРУГОЕ ПРИЛОЖЕНИЕ, работающее даже в другом домене приложения (но в том же процессе), может заблокировать ваше приложение, получив блокировку на объект типа, который вы хотите заблокировать, и никогда не освобождая его. И было бы легко получить доступ к этому объекту типа, потому что у объекта есть имя - полное имя типа! Помните, что блокировка / SyncLock блокирует (это вежливое слово для обозначения зависаний) до тех пор, пока не сможет получить блокировку. Очевидно, что очень плохо полагаться на блокировку, которую другая программа или компонент может заблокировать и вызвать тупиковую ситуацию.

60
ответ дан 26 November 2019 в 21:13
поделиться

It's the same problem as with lock(this) - you're locking on a reference which other code has access to, so it could be locking on it too.

If you have two unrelated pieces of code locking on the same reference without intending to exclude each other, then in the best case you could lose a bit of performance due to a lack of concurrency - and in the worst case you could introduce a deadlock.

27
ответ дан 26 November 2019 в 21:13
поделиться

Because the result of typeof (MyType) (which is an object of type Type) is widely accessible and other thread can lock on the same object, and hold that lock indefinitely. Then internal logic of MyType has effectively given away significant control over it's synchronization logic. This might not be an actual problem if this is intended, but coding defensively/skeptically should be your modus operandi.

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

because the target of a lock is ONLY to establish a place to store the lock boolean (Am I locked or not) for other threads to look at....

The common misconception that the target of a lock is actually somehow being locked is just wrong... What is "locked" is, .... nothing, unless in methods which can access some shared memory in an unsafe manner, you write the code to look at the this lock and not proceed until it has been released... using a Type object, as a lock target is wrong because code snippets anywhere in the entire solution process space can access that type object and change the synch block that the lock boolean is stored in. Creating a locally scoped object allows you to better ensurethat only those threads and methods that can access or mess with your "at risk" shared memory can also access and/or modify the lock.

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

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