Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
 Аватар для Rhoxolan
13 / 13 / 7
Регистрация: 16.12.2020
Сообщений: 247
.NET 6

Ожидание определенными потоками завершения одного определенного потока с использованием Monitor

01.09.2022, 22:32. Показов 855. Ответов 2

Студворк — интернет-сервис помощи студентам
Здравствуйте. Решаю сейчас следующую задачу: запускается 4 потока (например по нажатию кнопки где-то в WF), первый поток заполняет массив или список, а остальные - ищут минимум, максимум и среднее. Потоки запускаются поочередно построчно. Но так как нет гарантии, что первым запустится и "закроет дверь" секции именно поток заполнения массива, нужно все правильно синхронизировать так, чтобы потоки поиска значений в любом случае ожидали выполнения потока заполнения массива. Это задачу я уже решал с помощью AutoResetEvent примерно так:

ВНИМАНИЕ! ПИСАЛ ПРЯМО ТУТ ДЛЯ ПРИМЕРА, В IDE НЕ ПРОВЕРЯЛ
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
List<int> list = new();
AutoResetEvent waitHandler = new(false); //Инициализируем waitHandler в состоянии ожидания
 
private void button_Click(object sender, EventArgs e)
        {
            waitHandler.Reset(); //По нажатию кнопки в любом случае сбрасываем waitHandler в состояние ожидания
            Task.Run(InitializeList);
            int min = Task.Run(GetMin).Result;
            int max = Task.Run(GetMax).Result;
            double avg = Task.Run(GetAverage).Result;
        }
 
private void InitializeList()
        {
            list.Clear();
            Random random = new();
            for (int i = 0; i < 1000; i++)
            {
                list.Add(random.Next(0, 5001));
            }
            waitHandler.Set(); //Переводим в сигнальный режим, позволяя запуститься всем остальным потокам
        }
 
private int GetMin()
        {
            waitHandler.WaitOne();
            try
            {
                return list.Min();
            }
            finally
            {
                waitHandler.Set();
            }
        }
        
       //GetMax() и GetAverage() аналогичны GetMin()
Но задача у меня стоит следующая: Решить все это с использованием Monitir. А в дальнейшем - с использованием Mutex и Semaphore.
Вот и вопрос, хотя бы с Monitir - можно ли обеспечить ожидание определенными потоками завершения одного определенного потока с помощью него? Или для этих целей служат только ResetEvent-ы?
В любом случае, у меня есть варианты комбинировать примитивы, но интересно узнать, есть ли вариант сделать с помощью одного только Monitor.

Добавлено через 44 минуты
Лично я пришел к варианту комбинации Monitor и AutoResetEvent. Выглядит вполне понятно и приемлемо:

ВНИМАНИЕ! ВСЁ ТОТ ЖЕ НАПИСАННЫЙ ПРЯМО ТУТ КОД.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
List<int> list = new();
AutoResetEvent waitHandler = new(false); //Инициализируем waitHandler в состоянии ожидания
 
private void button_Click(object sender, EventArgs e)
        {
            waitHandler.Reset(); //По нажатию кнопки в любом случае сбрасываем waitHandler в состояние ожидания
            Task.Run(InitializeList);
            int min = Task.Run(GetMin).Result;
            int max = Task.Run(GetMax).Result;
            double avg = Task.Run(GetAverage).Result;
        }
 
private void InitializeList()
        {
            Monitor.Enter(list);
            try
           {
            list.Clear();
            Random random = new();
            for (int i = 0; i < 1000; i++)
            {
                list.Add(random.Next(0, 5001));
            }
            }
            finally
           {
           Monitor.Exit(list);
            waitHandler.Set(); //Переводим в сигнальный режим, позволяя запуститься всем остальным потокам
           }
        }
 
private int GetMin()
        {
            waitHandler.WaitOne();
            Monitor.Enter(list);
            try
            {
                return list.Min();
            }
            finally
            {
                Monitor.Exit(list);
                waitHandler.Set();
            }
        }
        
       //GetMax() и GetAverage() аналогичны GetMin()
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.09.2022, 22:32
Ответы с готовыми решениями:

Ожидание запуска и завершения процесса для работы с потоками ввода
здравствуйте. есть программа на vb, которая при работе запускает другой процесс, чтобы затем передать ему данные через stdin. сейчас...

Ожидание завершения потока
private void button1_Click(object sender, EventArgs e) { System.Threading.Thread MyThread1 = ...

Ожидание завершения потока
Доброго вечера. Подскажите...то я что то сам не разобрался... Как подождать завершения потока... // if (поток завершен) { ...

2
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
02.09.2022, 02:01
Цитата Сообщение от Rhoxolan Посмотреть сообщение
задача у меня стоит следующая: Решить все это с использованием Monitir
Это учебная задача, где имеется ограничение на использование только монитора или вы в реальном проекте хотите это реализовать?
Если второе, то зачем? Есть же более высокоуровневые конструкции для синхронизации.

Цитата Сообщение от Rhoxolan Посмотреть сообщение
нужно все правильно синхронизировать так, чтобы потоки поиска значений в любом случае ожидали выполнения потока заполнения массива
Используйте комбинацию методов Enter, Pulse и Wait:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
List<int> list = new();
object initLock = new();
object calcLock = new(); 
 
Monitor.Enter(initLock);
Task.Run(InitializeList);
Monitor.Wait(initLock);
 
var min = Task.Run(GetMin);
var max = Task.Run(GetMax);
var avg = Task.Run(GetAverage);
 
Task.WaitAll(min, max, avg);
 
void InitializeList()
{
    Monitor.Enter(initLock);
    Monitor.Enter(calcLock);
 
    Monitor.Pulse(initLock);
    Monitor.Exit(initLock);
 
    list.Clear();
    Random random = new();
    for (int i = 0; i < 1000; i++)
    {
        list.Add(random.Next(0, 5001));
    }
 
    Monitor.Exit(calcLock);
}
 
int GetMin()
{
    Monitor.Enter(calcLock);
    Monitor.Exit(calcLock);
    
    return list.Min();
}
 
int GetMax()
{
    Monitor.Enter(calcLock);
    Monitor.Exit(calcLock);
    
    return list.Max();
}
 
double GetAverage()
{
    Monitor.Enter(calcLock);
    Monitor.Exit(calcLock);
    
    return list.Average();
}
1
 Аватар для Rhoxolan
13 / 13 / 7
Регистрация: 16.12.2020
Сообщений: 247
02.09.2022, 09:33  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Это учебная задача, где имеется ограничение на использование только монитора или вы в реальном проекте хотите это реализовать?
Если второе, то зачем? Есть же более высокоуровневые конструкции для синхронизации.
Да, задача учебная. Про более высокоуровневые конструкции для синхронизации - это вы за какие?

Цитата Сообщение от kolorotur Посмотреть сообщение
Используйте комбинацию методов Enter, Pulse и Wait:
Спасибо, подумаю и над этим вариантом.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.09.2022, 09:33
Помогаю со студенческими работами здесь

Ожидание завершения потока
Всем привет. В цикле создаю и запускаю N потоков. Интересует как сделать чтобы главный поток ожидал завершения всех этих потоков, после...

Service, ожидание завершения потока serviceMain
Всем привет! Тема: winapi service Вопрос: как правильно реализуется ожидание завершения функции serviceMain ? Скорее всего я...

Порождение потока и ожидание его завершения
Задание: Процесс 1 порождает процесс-потомок, ждет его завершения, после этого порождает еще один процесс-потомок и так N раз. Каждый...

Остановка и возобновление работы потока с использованием класса Monitor
Здравствуйте! Одно из заданий к ЛР гласит: У меня есть потоки: private Thread examMoveThread; private Thread...

Ожидание завершения процесса
Привет, есть путь к файлу, есть файл, после запуска файл выполняет действия и закрывается. Задача: Отследить состояние файла по пути,...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru