Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.76/29: Рейтинг темы: голосов - 29, средняя оценка - 4.76
12 / 12 / 1
Регистрация: 05.04.2012
Сообщений: 127

Синхронизация потоков: проблема гонки потоков

20.10.2014, 03:58. Показов 5525. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть проблема в синхронизации потоков, которую я не знаю, как решить. Точнее у меня получается типичная гонка потоков.
Есть функция, которая меняет статический массив. Если два массива (а и б) равны, то поток завершает выполнение.
Вот сам код функции:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static void func(double[] arr)
        {
            Random rd = new Random();
            bool fl = true;
            while (fl)
            {
                
                //Случайно выбираем элемент массива
                int index = rd.Next(0, arr.Length);
                //Если 0, то мы обнуляем элемент, если 1, то умножаем на произвольное число от 1 до 10.
                int flag = rd.Next(0, 1);
                int number = rd.Next(1, 10);
                arr[index] = (flag == 0) ? 0 : arr[index] * number;
                lock (locker)
                {
                    if (Sum(a) == Sum(b)) fl = false;
                }
            }
            
        }

В чем казус? Когда один поток находится в лок, а другой в самом начале функции, первый успевает завершить действие (выходит из цикла), а второй в этот момент меняет значение, и получается условие не равно, и все...Как решить данную проблему, кто подскажет?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.10.2014, 03:58
Ответы с готовыми решениями:

Синхронизация потоков на элементарном уровне (переключение потоков)
в общем разбираюсь с потоками, на сколько понял мне нужен lock Вот имеется просто пример public void RunAdd() ...

Синхронизация потоков
Есть программа: using System; using System.Diagnostics; using System.Linq; using System.Runtime.ConstrainedExecution; using...

Синхронизация потоков
Здравствуйте! Я понимаю, что подобные вопросы уже много раз задавались, но перечитав подобные темы та и другую литературу, так и не смог...

7
Эксперт .NET
 Аватар для insite2012
5546 / 4309 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
20.10.2014, 05:36
Цитата Сообщение от MoonGuard Посмотреть сообщение
Как решить данную проблему
MoonGuard, у вас общий (разделяемый между потоками) ресурс это массив, так? Так почему вы тогда блокируете только небольшой участок кода, а не полностью все операции с общим ресурсом внутри потока? Заблокируйте полностью, ну или используйте потокобезопасные коллекции...
1
12 / 12 / 1
Регистрация: 05.04.2012
Сообщений: 127
20.10.2014, 10:22  [ТС]
insite2012, хм, просто если я заблокирую всю функцию, т.е. поставлю её в лок. Тогда в чем соль? Потоки будут выполняться по очереди, ну или кто первый захватит, т.е. потеряю всю параллельность.
Соль такая: у меня есть два массива статических. Один поток работает с одним массивом, другой с другим. В тот момент, когда сумма этих массивов равна, работу надо прекращать. Т.е. общий элемент между потоками - это сравнение вот этих массивов. Получается по логике, надо как-то после каждого изменения в массиве, не важно в каком, вызывать эту функцию, при этом останавливая выполнения всех потоков и возможность прерывания их работы. Единственное, что пришло в голову, это тот код что выше, но моя логика либо неправильна, либо неполна, т.к. возникает вот такой казус не разрешенный. Может вы что подскажите?
0
814 / 422 / 169
Регистрация: 08.02.2013
Сообщений: 711
20.10.2014, 10:57
MoonGuard, а если так?: каждый поток работает с копией своего массива, вычисляется сумма элементов, общие ресурсы это оригиналы массивов и суммы, лочится процесс сохранения новой суммы и подмены оригинала массива копией. Если после обработки копии старые суммы совпадают то завершаем поток без подмены массива.
1
 Аватар для Defazze
325 / 136 / 28
Регистрация: 18.09.2014
Сообщений: 167
20.10.2014, 11:09
Лучший ответ Сообщение было отмечено MoonGuard как решение

Решение

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

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

Итого вырисовывается след. решение:

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
private static bool _isEqual = false;
static void func(double[] arr)
        {
            Random rd = new Random();
            bool fl = true;
            while (!_isEqual )
            {
                
                //Случайно выбираем элемент массива
                int index = rd.Next(0, arr.Length);
                //Если 0, то мы обнуляем элемент, если 1, то умножаем на произвольное число от 1 до 10.
                int flag = rd.Next(0, 1);
                int number = rd.Next(1, 10);
 
                lock (locker)
                {
                    if(!_isEqual)
                    {
                       arr[index] = (flag == 0) ? 0 : arr[index] * number;
                       if (Sum(a) == Sum(b)) _isEqual = true;
                    }
                }
            }      
        }
1
Эксперт .NET
 Аватар для insite2012
5546 / 4309 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
20.10.2014, 11:15
Цитата Сообщение от MoonGuard Посмотреть сообщение
Может вы что подскажите?
Тогда, если я верно понял, вам действительно нужна синхронизация. Попробуйте использовать для этого класс EventWaitHandler.
1
Эксперт .NET
 Аватар для kolorotur
17818 / 12969 / 3381
Регистрация: 17.09.2011
Сообщений: 21,253
20.10.2014, 11:20
Цитата Сообщение от MoonGuard Посмотреть сообщение
C#
1
int flag = rd.Next(0, 1);
Не по теме, но оно же всегда 0 будет, не?
1
12 / 12 / 1
Регистрация: 05.04.2012
Сообщений: 127
20.10.2014, 13:35  [ТС]
kolorotur, да вы правы. Я совершенно забыл, что там max-1 значение будет. Просто для повышения вероятности стояло 3 и тесты ошибок не выдавали. После исправил, и забыл про сей важный факт.
Думаю проблему можно считать решенный, всем спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.10.2014, 13:35
Помогаю со студенческими работами здесь

Синхронизация потоков с#
Здравствуйте. Задача у меня такая: нужно, чтобы три потока асинхронно брали из List слова и записывали их в файл, предварительно приведя к...

Синхронизация потоков c#
Задача о парикмахере. В городе есть салон-парикмахерская, в которой работает только один парикмахер. Когда в салоне никого нет,...

Синхронизация потоков
Есть ли возможность в C# сделать часть кода потока защищенным от прерывания другими потоками. Lock не подходит, т.к. потоки не используют...

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

Синхронизация потоков
Не так давно начал заниматься c#.. возникла следующее недопонимание потоков. Программа ищет в цикле случайное число от 0 до 10, цикл...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Создание нейросети с PyTorch
AI_Generated 19.06.2025
Ключевое преимущество PyTorch — его питоновская натура. В отличие от TensorFlow, который изначально был построен как статический вычислительный граф, PyTorch предлагает динамический подход. Это. . .
JWT аутентификация в ASP.NET Core
UnmanagedCoder 18.06.2025
Разрабатывая веб-приложения, я постоянно сталкиваюсь с дилеммой: как обеспечить надежную аутентификацию пользователей без ущерба для производительности и масштабируемости? Классические подходы на. . .
Краткий курс по С#
aaLeXAA 18.06.2025
Здесь вы найдете все необходимые функции чтоб написать програму на C# Задание 1: КЛАСС FORM 1 public partial class Form1 : Form { Spisok listin = new Spisok(); . . .
50 самых полезных примеров кода Python для частых задач
py-thonny 17.06.2025
Эффективность работы разработчика часто измеряется не количеством написаных строк, а скоростью решения задач. Готовые сниппеты значительно ускоряют разработку, помогают избежать типичных ошибок и. . .
C# и продвинутые приемы работы с БД
stackOverflow 17.06.2025
Каждый . NET разработчик рано или поздно сталкивается с ситуацией, когда привычные методы работы с базами данных превращаются в источник бессонных ночей. Я сам неоднократно попадал в такие ситуации,. . .
Angular: Вопросы и ответы на собеседовании
Reangularity 15.06.2025
Готовишься к техническому интервью по Angular? Я собрал самые распространенные вопросы, с которыми сталкиваются разработчики на собеседованиях в этом году. От базовых концепций до продвинутых. . .
Архитектура Onion в ASP.NET Core MVC
stackOverflow 15.06.2025
Что такое эта "луковая" архитектура? Термин предложил Джеффри Палермо (Jeffrey Palermo) в 2008 году, и с тех пор подход только набирал обороты. Суть проста - представьте себе лук с его. . .
Unity 4D
GameUnited 13.06.2025
Четырехмерное пространство. . . Звучит как что-то из научной фантастики, правда? Однако для меня, как разработчика со стажем в игровой индустрии, четвертое измерение давно перестало быть абстракцией из. . .
SSE (Server-Sent Events) в ASP.NET Core и .NET 10
UnmanagedCoder 13.06.2025
Кажется, Microsoft снова подкинула нам интересную фичу в новой версии фреймворка. Работая с превью . NET 10, я наткнулся на нативную поддержку Server-Sent Events (SSE) в ASP. NET Core Minimal APIs. Эта. . .
С днём независимости России!
Hrethgir 13.06.2025
Решил побеседовать, с утра праздничного дня, с LM о завоеваниях. То что она написала о народе, представителем которого я являюсь сам сначала возмутило меня, но дальше только смешило. Это чисто. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
OSZAR »