Что быстрее, блокировка или Thread.Interrupt? - PullRequest
2 голосов
/ 09 июня 2011

У меня есть программа, которая включает получение пакета из сети в одном потоке, а затем уведомление других потоков о получении пакета. Мой текущий подход использует Thread.Interrupt, который кажется немного медленным при передаче огромных объемов данных. Будет ли быстрее использовать «блокировку», чтобы избежать использования многих прерываний, или блокировка действительно просто вызывает Interrupt () в своей реализации?

Ответы [ 3 ]

2 голосов
/ 09 июня 2011

Я не понимаю, почему вы бы использовали Thread.Interrupt, а не какой-то более традиционный метод сигнализации для уведомления ожидающих потоков о получении данных.Thread.Interrupt требует, чтобы целевой поток в любом случае находился в состоянии ожидания, так почему бы просто не добавить объект, который вы можете сигнализировать в логику ожидания целевого потока, и использовать его для запуска новых данных?

lock используется для защиты критического кода или данных от выполнения другими потоками и плохо подходит в качестве механизма для активной межпотоковой сигнализации.

Используйте WaitOne или WaitAll на подходящем объекте (ах) вместо любого.System.Collections.Concurrent в .Net 4 также предоставляет отличные средства для помещения новых данных в очередь целевых потоков и других возможных подходов к вашей проблеме.

1 голос
/ 09 июня 2011

И Thread.Interrupt, и lock плохо подходят для сигнализации других потоков.

  • Thread.Interrupt используется для нажатия или снятия блокировки одного из блокирующих вызовов в BCL.
  • lock используется для предотвращения одновременного доступа к ресурсу или блоку кода.

Передача сигналов другим потокам лучше осуществляется с помощью одного из следующих механизмов.

0 голосов
/ 09 июня 2011

Я обычно использую стандартную очередь и ключевое слово lock при чтении или записи. Кроме того, метод Synchronized в очереди устраняет необходимость использования блокировки. System.Threading.Semaphore - лучший инструмент для уведомления рабочих потоков о появлении новых заданий для обработки.

Пример добавления в очередь

lock ( myQueue) { myQueue.Enqueue(workItem); }
mySemaphore.Release();

Пример обработки рабочего элемента:

mySemaphore.WaitOne();
lock (myQueue) { object workItem = myQueue.Dequeue(); }
// process work item

Настройка семафора:

mySemaphore = new Semaphore(0, int.MaxValue);

Если это слишком медленно, и накладные расходы на синхронизацию по-прежнему преобладают в вашем приложении, вы можете рассмотреть возможность отправки более одного рабочего элемента за раз.

В зависимости от того, что вы делаете, новые функции распараллеливания в .NET 4.0 также могут быть очень полезны для вашего приложения (если это вариант).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...