Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/34: Рейтинг темы: голосов - 34, средняя оценка - 4.82
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236

Доступ к очереди из разных потоков

25.06.2015, 13:49. Показов 6778. Ответов 11

Студворк — интернет-сервис помощи студентам
Подскажите по многопоточности, у меня есть очередь (Queue) и мне надо организовать к ней доступ из разных потоков, выискал несколько решений, одно из них использовать ключевое слово lock, а так же можно использовать классы Mutex, Monitor, возник вопрос при использовании Monitor, Monitor.Enter блокирует потоки пока не будет выполнен код между ним и Monitor.Exit, собственно вопрос, а зачем тогда метод Monitor.TryEnter? может быть такое что Monitor.Enter не сможет заблокировать поток? или как или что?
Так же что то подобное я встречал классе ConcurrentQueue, в частности метод TryDequeue.

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

C#
1
2
3
4
5
6
7
8
9
lock(lockObj) {
    string temp = data.Dequeue();
}
 
// или 
 
Monitor.Enter(lockObj);
string temp = data.Dequeue();
Monitor.Exit(lockObj);
у меня сразу блокируются все остальные потоки или только тогда, когда эти другие потоки дойдут до конструкции lock или Monitor.Enter?

если не понятно, на примере, допустим я получаю HTML код странницы и далее в конструкции lock я эти данные помещаю в Queue, я начал получать HTML и тут вдруг блокировка потока, вроде как такое может закончится не корректно или потоки остановятся когда дойдут до конструкции lock?

Добавлено через 5 минут
читал msdn и еще некоторые источники но то ли я тупой то ли там очень скудное описание всего это.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.06.2015, 13:49
Ответы с готовыми решениями:

Организовать доступ к элементам очереди из двух потоков
1 поток добавляет элементы в очередь. 2 дргуих должны счиать кждый элемент очереди. Как наилучшим образом организовать считываение...

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

Обезопасить доступ к коллекции из разных потоков
станет ли безопасным метод AddSafe? public static MyCollection myCol = new MyCollection(); class MyCollection:...

11
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
25.06.2015, 14:04
Цитата Сообщение от VLK Посмотреть сообщение
а зачем тогда метод Monitor.TryEnter?
Для попытки взять право на пользование общим ресурсом без блокировки текущего потока.

Цитата Сообщение от VLK Посмотреть сообщение
может быть такое что Monitor.Enter не сможет заблокировать поток?
Конечно может — если ресурс не занят другим потоком, то блокировки текущего не будет.

Цитата Сообщение от VLK Посмотреть сообщение
когда я пытаюсь заблокировать потоки что бы выполнить код в одном из потоков, у меня сразу блокируются все остальные потоки или только тогда, когда эти другие потоки дойдут до конструкции lock или Monitor.Enter?
Когда дойдут до конструкции при условии, что lockObj ссылается на один и тот же объект.

Цитата Сообщение от VLK Посмотреть сообщение
допустим я получаю HTML код странницы и далее в конструкции lock я эти данные помещаю в Queue, я начал получать HTML и тут вдруг блокировка потока, вроде как такое может закончится не корректно или потоки остановятся когда дойдут до конструкции lock?
Зависит от того, какие участки кода вы блокируете для других потоков.
1
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
25.06.2015, 14:16  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Для попытки взять право на пользование общим ресурсом без блокировки текущего потока.
Цитата Сообщение от kolorotur Посмотреть сообщение
Конечно может — если ресурс не занят другим потоком, то блокировки текущего не будет.

хм.. а разве оно не работает по принципу что запускается метод Monitor.Enter и его выполнение будет закончено ровно тогда, когда для его потока наступит очередь, ну т.е. короче, есть 15 потоков, допустим 5-й поток доходит до Monitor.Enter но сейчас выполняются другие потоки по этому 5-й поток пока стоит в ожидании, а именно ожидание происходит в методе Monitor.Enter, когда только наступит очередь 5-го потока, тут же будет завершен вызов Monitor.Enter 5-го потока и будет выполнятся код между Monitor.Enter и Monitor.Exit

Я не знаю, но просто по логике вроде как так должно быть, правда зачем тогда два метода, они взаимоисключающие.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
25.06.2015, 14:26
Цитата Сообщение от VLK Посмотреть сообщение
запускается метод Monitor.Enter и его выполнение будет закончено ровно тогда, когда для его потока наступит очередь
Да, только не используйте слово "очередь" — там очереди в понимании "первый пришел — первый получил" нет.
Если ресурс не занят или только что освободился, то следующим его может захватить любой из 14-и ждущих потоков.

Цитата Сообщение от VLK Посмотреть сообщение
по логике вроде как так должно быть
Так и есть!

Цитата Сообщение от VLK Посмотреть сообщение
зачем тогда два метода, они взаимоисключающие.
Почему взаимоисключающие?
Monitor.Enter — попытаться взять права на использование ресурсом, если ресурс занят — ждать, пока не освободится.
Monitor.TryEnter — попытаться взять права на использование ресурсом, если занят — вернуть false, если был свободен и сейчас занят мной, то вернуть true. В любом случае продолжать дальнейшую работу.

Вроде никакого взаимоисключения.
1
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
25.06.2015, 14:43  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Почему взаимоисключающие?
а, то есть различие их примерно такое (по логике), Enter если участок кода занят, жди пока освободится, а у TryEnter если участок кода НЕ занят, выполнял, а если занят, можешь пока что то другое сделать, ну и в коде это выглядит как то так:
C#
1
2
3
4
5
6
7
8
9
if (Monitor.TryEnter(lockObj))
{
    // не занято, выполняй
    Monitor.Exit(lockObj);
}
else
{
    // пока занято, сделаю что то еще
}
так?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
25.06.2015, 14:52
Лучший ответ Сообщение было отмечено VLK как решение

Решение

Цитата Сообщение от VLK Посмотреть сообщение
так?
Так, только правильная семантика не "пока занято, сделаю что-то другое", а "раз уж занято, то буду делать что-то другое".
Первое подразумевает, что как только ресурс освободится, выполнение автоматом перепрыгнет в блок "не занято, выполняй".
На деле же, если в вашем коде ресурс занят, то блок "не занято, выполняй", будет просто пропущен. Чтобы его выполнить, вам придется самим кодить возвращение к этому блоку, например помещая условие в цикл.
1
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
25.06.2015, 15:02  [ТС]
можно еще такой вопрос, по теме, а вот какие еще классы и ключевые слова существуют для работы с многопоточностью, я знаю о lock, классы Thread, Task, Monitor, Mutex, Semaphore, Interlocked, Parallel ну и я читал про async и await методы.
может есть какая статья, где был описывались все средства для работы с многопоточностью?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
25.06.2015, 15:07
Цитата Сообщение от VLK Посмотреть сообщение
а вот какие еще классы и ключевые слова существуют для работы с многопоточностью? может есть какая статья, где был описывались все средства для работы с многопоточностью?
Все классы описаны в документации, достаточно глянуть описание пространства System.Threading.
Тыкая на каждый класс можно посмотреть его описание, применение и пример использования.

Цитата Сообщение от VLK Посмотреть сообщение
может есть какая статья, где был описывались все средства для работы с многопоточностью?
Как правило в книжках по программированию описывают различные подходы для решения различных задач.
Мне очень нравится серия "C# In a Nutshell" братьев Альбахари.
1
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
25.06.2015, 17:27  [ТС]
kolorotur, еще такой вопрос забыл уточнить, если я в одном месте использую
C#
1
2
3
lock(lockObj) {
    // ....
}
а в другом:
C#
1
2
3
Monitor.Enter(lockObj);
string temp = data.Dequeue();
Monitor.Exit(lockObj);
но объект lockObj общий, это нормально будет работать?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
25.06.2015, 19:27
VLK, да, главное не мешайте их в одном блоке.

lock — это синтаксический сахар для Monitor.Enter/Exit, конструкция lock(obj) { ... } разворачивается компилятором примерно в такую:
C#
1
2
3
4
5
6
7
8
9
Monitor.Enter(obj);
try
{
   ...
}
finally
{
   Monitor.Exit(obj);
}
1
 Аватар для VLK
198 / 170 / 19
Регистрация: 05.05.2013
Сообщений: 1,236
14.08.2015, 12:24  [ТС]
kolorotur, еще такой вопрос возник

C#
1
2
3
4
5
6
7
8
9
10
11
12
List<int> temp = new List<int>();
 
// ....
//  в потоках:[
 
for (int i = 0; i < 100; i++)
{
    Monitor.Enter(temp);
    if (i == 50) break;
    temp.Add(temp.Count);
    Monitor.Exit(temp);
}
я делаю break до Monitor.Exit, все закончится печально?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
14.08.2015, 13:43
Цитата Сообщение от VLK Посмотреть сообщение
все закончится печально?
Да.

С другой стороны, возникает два вопроса:
1. Зачем вы лочитесь на проверке i? Она является локальной переменной цикла, не изменяется другими потоками (если где-то за пределами цикла нет захвата), то есть не является общим ресурсом, а значит ей не место в критической зоне.

Вносите в критическую зону только те участки кода, которые непосредственно работают с общими ресурсами:
C#
1
2
3
4
    if (i == 50) break;
    Monitor.Enter(temp);
    temp.Add(temp.Count);
    Monitor.Exit(temp);
2. Зачем вообще проверка на i? Вы на стадии написания кода уже знаете, что цикл идет максимум до i=50, дык сделайте это условием цикла:
C#
1
2
3
4
5
6
for (int i = 0; i < 50; i++)
{
    Monitor.Enter(temp);
    temp.Add(temp.Count);
    Monitor.Exit(temp);
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.08.2015, 13:43
Помогаю со студенческими работами здесь

Доступ к БД с разных потоков
как реализовать доступ к одной базе данных с разных потоков? когда один сервер обрабатывает несколько клиентов то у меня выходит...

Доступ к функции с разных потоков C++ Builder
Как правильно объявить/создать функцию в C++Builder, чтобы она была доступна со всех потоков, включая главный? И как потом в этой функции...

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

Доступ к файлам из разных потоков, как исключить коллизии?
Разные потоки осуществляют чтение разных файлов произвольным образом командой System.IO.FileStream(NameFile, FileMode.Open). Иногда, при...

Выполнение потоков по очереди
Здравствуйте, изучаю книгу Шилдта и возник вопрос в многопоточности, а именно этот пример: package Synch; class Callme { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru