Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 17.10.2013
Сообщений: 10

Потокобезопасность, найти ошибки в коде

01.04.2014, 23:37. Показов 1173. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем.
Есть код обхода в ширину. Я хочу использовать пр этом несколько потоков, как я понимаю необходимо сделать очередь потокобезопасной (что я и сделал), но все равно появляется ошибка что очередь уже пуста, когда из нее пытаюсь удалить элемент. Примитивы многопоточности я знаю, только никогда не писал многопоточный код. Помогите пожалуйста.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        public void start()
        {
            mainQueue.Enqueue(rootState);
            lock (mainQueue.SyncRoot)
            {
                while (mainQueue.Count != 0)
                {
                    Thread newThread = new Thread(new ThreadStart(this.functionIteration));
                    newThread.Start();
                }
            }
        }
 
        private void functionIteration()
        {
//ТУт ошибка!!!!!
            State tempState = (State)mainQueue.Dequeue();
           if(..) {
                        mainQueue.Enqueue(s);
            }
        }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.04.2014, 23:37
Ответы с готовыми решениями:

Найти ошибки в коде и исправить эти ошибки (Наследование)
Вот в общем 3 файла, изучаю наследование на примере односвязного и двусвязного списков: list.h (inline) #pragma once class list...

Найти ошибки в коде и исправить эти ошибки - C++
Судя по вываливающейся ошибки, идет двойное освобождение памяти. У самого не получается отловить откуда. A.h #pragma once ...

Найти ошибки в коде и исправить эти ошибки
Есть у меня вот такой код: #include <iostream> using namespace std; class A{ private: int* a; size_t size_; ...

10
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
02.04.2014, 12:32
Привет!
Синхронизацию надо делать не при создании потоков, а при их выполнении.
Потому перенесите блок lock в метод functionIteration
0
0 / 0 / 0
Регистрация: 17.10.2013
Сообщений: 10
02.04.2014, 20:35  [ТС]
Если я вас правильно понял...
Но данный вариант так же не спасает от описанной ранее ошибки.
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
public void start()
        {
            //run обход в ширину
            //Поместить узел, с которого начинается поиск, в изначально пустую очередь.
            mainQueue.Enqueue(rootState);
            visited.Add(rootState);
            allStates.Add(rootState);
           // lock (mainQueue.SyncRoot)
            //{
                while (mainQueue.Count != 0)
                {
                    Thread newThread = new Thread(new ThreadStart(this.functionIteration));
                    newThread.Name = DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString() + ":" + DateTime.Now.Millisecond.ToString();
                    newThread.Start();
                }
          //  }
        }
 
        private void functionIteration()
        {
            lock (mainQueue.SyncRoot)
            {
                Console.WriteLine("!!!{0} has entered in functionIteration.",
                    Thread.CurrentThread.Name);
                //Извлечь из начала очереди узел U и пометить его как развёрнутый.
                State tempState = null;
                    tempState = (State)mainQueue.Dequeue();
 
                tempState.showState();
                //Если узел U является целевым узлом, то завершить поиск с результатом «успех».
                if (tempState.Equals(goalState))
                {
                    solutions++;
                    return;
                }
                else
                {
                    //генерируем детей
                    generateChildStates(tempState);
                    //В противном случае, в конец очереди добавляются все преемники узла , которые ещё не развёрнуты и не находятся в очереди.
                    foreach (State s in tempState.childState)
                    {
                        if (!visited.Contains(s) || s.Equals(goalState))
                        {
                            mainQueue.Enqueue(s);
                            visited.Add(s);
                        }
                    }
                }
            }
        }
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
02.04.2014, 21:01
Смотри что ты делаешь:

Закидываешь в очередь один элемент, далее запускаешь цикл, который пока очередь не пустая, стартует новый поток.

Закинули один элемент с очередь.

смотрим количество -- один. Создаем поток #1 (допустим он пока только создался и запустился).
смотрим количество -- один (мы же ещё ничего не тянули). создался поток #2
смотрим количество ........... создали поток #3
и так пока не надоест (а что? боги не несут ответственности за порядок выполнения потоков)

поток #1 получает время на работу с процом. Тянем элимент из очереди. Время закончилось.
поток #2 получает время на работу. Тянем из очереди....

P.S. http://msdn.microsoft.com/ru-r... Z5XKjdjJO9
P.Р.S. создание потока должно происходить по получению элемента из очереди, а не в неконтролируемом цикле, который смотрит количество и ничего с этим количество не делает.
0
0 / 0 / 0
Регистрация: 17.10.2013
Сообщений: 10
02.04.2014, 21:54  [ТС]
Да, я примерно так и думал, только вот немного непонятно как это воплотить в коде. я ведь не могу вынять элемент из очереди в цикле, создать поток и сделать что-то типа:
C#
1
Thread newThread = new Thread(new ThreadStart(this.functionIteration(element)));
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
03.04.2014, 10:52
Ikimura, у вас ошибка именно в организации потоков, ведь вы на каждый элемент очереди стартуете новый поток, что не увеличивает производительность, а наоборот — уменьшает ее, так как создание и запуск потока весьма дорогостоящая операция.
Вместо этого просто создайте несколько рабочих потоков — по одному-двум на ядро будет достаточно, и в каждом из потоков уже обрабатывайте в цикле очередь до тех пор, пока она не будет пустой.
0
52 / 45 / 4
Регистрация: 07.10.2010
Сообщений: 95
03.04.2014, 15:07
Читая очередую тему тут о многопоточности всегда удивлялся, почему везде Thread newThread = new Thread???
Вродне как вторая версия фреймворка закончилась чуть ли не 10 лт назад, но почему то студентам так и не рассказывают о task, plinq, parallel, blockingCollections...
Вот и тут. Почему бы не использовать ConcurrentQueue и реализовать паттерн Produser-Consumer используя современные средства С#. Как раз это и есть решение этой задачи.
0
0 / 0 / 0
Регистрация: 17.10.2013
Сообщений: 10
03.04.2014, 20:32  [ТС]
Амм.....Пример бы небольшой. Не совсем понимаю, как это реализовать....
А за совет, спасибо.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
03.04.2014, 21:17
Цитата Сообщение от Ikimura Посмотреть сообщение
Пример бы небольшой.
С Гуглом поссорились?
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
03.04.2014, 22:07
Цитата Сообщение от serefa Посмотреть сообщение
Читая очередую тему тут о многопоточности всегда удивлялся, почему везде Thread newThread = new Thread???
По той же причине, студентам сначала объясняют if с for, а уже потом foreach и оператор "?" -- так проще понять.
0
0 / 0 / 0
Регистрация: 17.10.2013
Сообщений: 10
06.04.2014, 15:45  [ТС]
serefa, не могу разобраться немного с архитектурой, про паттерн прочитал, примеры посмотрел. У меня есть общая очередь состояний. И обход в ширину, который использует эту очередь. В нем когда из очереди выбирается очередное состояние, для него генерируются чайлды - genereateChildFor(State s). Я не могу понять как мне грамотно разнести ответсвенности Producer/Consumer между имеющимися функциями. я так понимаю в качестве Producer-а должна выступать функция, которая геренирует чайлдов??? и как тогда реализовать Consumer-ов???? Схема функций есть в постах выше.
Спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.04.2014, 15:45
Помогаю со студенческими работами здесь

Найти ошибки в коде
#include <stdio.h> #include <conio.h> #include <math.h> int main () { float x,y; printf ("vvedite x:"); scanf...

Найти ошибки в коде
i:=length(s); foreach a:string in s.Split(('.!?').ToCharArray,system.StringSplitOptions.RemoveEmptyEntries) do if...

Найти ошибки в коде
задача из книги не работает, в чем могут быть опечатки #include <iostream> #include <cstring> using namespace std; int...

найти ошибки в коде
# include <stdio.h> # include <conio.h> int menu(int kp, char*NAZ); void main(void); int zadacha3 (int n, float *a, float...

Найти ошибки в коде
string a = Console.ReadLine(); string words = a.Split('*', '=');//разбиваем на 2 слова int perevod1=...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru