Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Satansoft
8 / 8 / 1
Регистрация: 27.02.2012
Сообщений: 725
#1

Ошибки в многопоточном вычислении средствами с++11 - C++

22.11.2014, 18:41. Просмотров 264. Ответов 13
Метки нет (Все метки)

Задачка:
20 детей едят из одной миски, в которой 100 слив, когда ребенок хочет кушать, он берёт из миски одну сливу, только если миска не пуста, если же пуста - зовёт маму, чтобы та наполнила её (соотвественно 100 слив), создать многопоточное приложение, реализующее задачу.

Есть класс MainWindow, в котором определены 3 метода:

Готовка:
C++
1
2
3
4
5
6
int Cooking_a()
        {
            int food=M;
 
            return food;
        }
Обед:
C++
1
2
3
4
5
6
7
8
9
10
 int Dinner_a(int food)
        {
            std::mutex eating;
            eating.lock();
            cout<< "Child ate";
            food--;
            eating.unlock();
 
            return 0;
        }
Вызов:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int Call_f()
{
std::thread Cannibals[N];
    while(true)
    {
        std::thread cook = std::thread(&MainWindow::Cooking_a, this);
        cook.join();
 
        int food=Cooking_a(); 
 
 
        for(int i=0;i<food;i++)
                {
                   int coven = M;
                   Cannibals[i] = std::thread(&MainWindow::Dinner_a, this, coven);
                   coven --;
                   Cannibals[i].join(); 
                }
}
 
    }
Вызов Call_f() происходит из main. На этапе выполнения программа зависает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.11.2014, 18:41
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Ошибки в многопоточном вычислении средствами с++11 (C++):

Ошибки в вычислении константы е - C++
Сделал программку, которая вычисляет константу Е для небольшого количества знаков после запятой. Помогите, пожалуйста, найти ошибку и...

Нужно найти ошибки в вычислении локального минимума - C++
Как новичку конечно же сложно по-нормальному что-то сделать,но думаю эта штука может работать. // Элемент матрицы называется локальным...

Ошибки: Неуместная рекурсия при вычислении миноров - C++
Неуместная рекурсия. double det(dpuble *a, int n) { double ***minors; double result; int m; int i; int j; if (n==2) ...

При вычислении функции arccos и преобразовании её в arctg возникают ошибки. - C++
Надо вычислить. #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; #define sqr(t) ((t) * (t)) #define sqrt(t) ((t) / (t)) ...

обход папок в многопоточном режиме - C++
Помогите реализовать данный код в многопоточном режиме. Заранее спасибо. Я не особо понимаю в чем ошибки, проверьте пожалуйста. inline...

Передача параметров в многопоточном приложении - C++
Здравствуйте! Есть вот такой рабочий кусочек кода: Thread^ myThread1 = gcnew Thread(gcnew ThreadStart(this,&amp;Form1::sayHello)); ...

13
nmcf
6084 / 5395 / 1880
Регистрация: 14.04.2014
Сообщений: 22,399
22.11.2014, 18:46 #2
mutex должен быть общий для всех потоков, а ты его в каком-то одном объявил.
1
Satansoft
8 / 8 / 1
Регистрация: 27.02.2012
Сообщений: 725
22.11.2014, 18:52  [ТС] #3
Цитата Сообщение от nmcf Посмотреть сообщение
mutex должен быть общий для всех потоков, а ты его в каком-то одном объявил.
Допустим, вынес его в верх секции public, хоть и взаимодействует с массивом потоков, которые получают доступ только к Dinner_a(), в котором он был объявлен локально. Ошибка точно не в этом, она по прежнему виснет, скорее всего где-то на возвращаемых значениях, или счетчик не считает и из-за бесконечного цикла виснет, но не вижу где...
0
nmcf
6084 / 5395 / 1880
Регистрация: 14.04.2014
Сообщений: 22,399
22.11.2014, 19:02 #4
Ты пойми, что использованием "карманного" mutex'а, объявленного в самой функции бессмысленно.

Добавлено через 3 минуты
Я не понял, что ты пытаешься сделать. 20 + 1 поток?
0
Satansoft
8 / 8 / 1
Регистрация: 27.02.2012
Сообщений: 725
22.11.2014, 19:05  [ТС] #5
Цитата Сообщение от nmcf Посмотреть сообщение
Я не понял, что ты пытаешься сделать. 20 + 1 поток?
20 детей едят из одной миски, в которой 100 слив, когда ребенок хочет кушать, он берёт из миски одну сливу, только если миска не пуста, если же пуста - зовёт маму, чтобы та наполнила её (соотвественно 100 слив), создать многопоточное приложение, реализующее задачу.

20 потоков детей, которые кушают 100 слив по очереди (спасибо мьютексу) и 1 поток мамы, которая восполняет миску сливами в полном объеме. Фактически: декремент объекта класса и по достижении 0 - переинициализация 100.
0
nmcf
6084 / 5395 / 1880
Регистрация: 14.04.2014
Сообщений: 22,399
22.11.2014, 19:24 #6
Ну и где у тебя это? Где 20 потоков создаётся? Там какой-то бесконечный цикл и цикл до food.
0
Satansoft
8 / 8 / 1
Регистрация: 27.02.2012
Сообщений: 725
22.11.2014, 19:31  [ТС] #7
Цитата Сообщение от nmcf Посмотреть сообщение
Где 20 потоков создаётся?
Создаем потоки
C++
1
std::thread Cannibals[N];
C++
1
2
3
4
5
6
7
 for(int i=0;i<food;i++) // Если миска не пуста
                {
                   int coven = M; // изначально инициализируем миску сливами
                   Cannibals[i] = std::thread(&MainWindow::Dinner_a, this, coven);//ребёнок кушает
                   coven --; // счетчик слив
                   Cannibals[i].join(); //завершение процесса
                }
0
demmax2004
60 / 138 / 35
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
22.11.2014, 19:37 #8
бесконечный цикл на строчках 4 и 5, который порождает миллионы и дохренилионы потоков
0
Satansoft
8 / 8 / 1
Регистрация: 27.02.2012
Сообщений: 725
22.11.2014, 19:41  [ТС] #9
Цитата Сообщение от demmax2004 Посмотреть сообщение
бесконечный цикл на строчках 4 и 5, который порождает миллионы потоков
Массив потоков объявлен, их 20, а бесконечный цикл направлен на постоянное повторение действий (ребёнок 1...n взял(и) сливу-> если сливы закончились, мама принесла ещё), правильней, конечно задержку поставить секунд в 5, чтобы не выполнялись очень быстро...
0
nmcf
6084 / 5395 / 1880
Регистрация: 14.04.2014
Сообщений: 22,399
22.11.2014, 19:41 #10
Мне кажется, как-то так должно быть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void mother()
{
    coven += 100;
}
void child()
{
    while(...) --coven;
}
//...
coven = 100;
for(int i = 0; i < 20; ++i)
    Cannibals[i] = std::thread(child);
    std::thread m = std::thread(mother);
for(int i = 0; i < 20; ++i)
    Cannibals[i].join();
m.join();
И вот это всё надо синхронизировать по доступу к coven.
1
Satansoft
8 / 8 / 1
Регистрация: 27.02.2012
Сообщений: 725
22.11.2014, 19:49  [ТС] #11
Цитата Сообщение от nmcf Посмотреть сообщение
void mother()
{
* * coven += 100;
}
маме надлежит возвращать значение в вызов и детям количество оставшихся слив тоже... под мьютекс загнать --coven и джойны в различных циклах, это мне пожалуй надо поправить, вдруг от этого виснет...
0
nmcf
6084 / 5395 / 1880
Регистрация: 14.04.2014
Сообщений: 22,399
22.11.2014, 19:56 #12
Зачем возвращать? Это часть задания?
0
Satansoft
8 / 8 / 1
Регистрация: 27.02.2012
Сообщений: 725
22.11.2014, 20:22  [ТС] #13
Цитата Сообщение от nmcf Посмотреть сообщение
Зачем возвращать? Это часть задания?
Нет, но как сделать нечто подобное циклически?

Алгоритм:
1. Инициализируем переменную миски сливами (100).
2. Создаем массив потоков (20)
3. Создаем поток мамы
4. 20 потоков по очереди декрементируют переменную в цикле
5. По достижению 0, она переинициализируется 100 и всё повторяется

Если не возвращать значение переменной, то как переинициализировать?

Добавлено через 19 минут
Переделал и заработало с 1 "НО": 20 детей-потоков, а слив 100, они по одной взяли и наелись...остальные 80 лежат, как разрешить недоразумение, сгниют же?
0
DrOffset
7517 / 4513 / 1024
Регистрация: 30.01.2014
Сообщений: 7,362
22.11.2014, 21:47 #14
Цитата Сообщение от Satansoft Посмотреть сообщение
Алгоритм:
1. Инициализируем переменную миски сливами (100).
2. Создаем массив потоков (20)
3. Создаем поток мамы
4. 20 потоков по очереди декрементируют переменную в цикле
5. По достижению 0, она переинициализируется 100 и всё повторяется
Условие выхода, нужные задержки, вывод в консоль добавишь сам по вкусу.
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
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
//#include <unistd.h>
 
std::mutex foodMutex;
std::condition_variable foodCond;
 
int plums = 100;
 
void child()
{
    while(1)
    {
        {
            std::unique_lock<std::mutex> lk(foodMutex);
            if(plums == 0) // сливы кончились
            {
                foodCond.notify_one(); // извещаем мамашу
                foodCond.wait(lk, [] { return plums > 0; }); // ждем наполнения тарелки
            }
            --plums;
            //std::cout << "plums left: " << plums << std::endl;
        }
        //usleep(500000);
    }
}
 
int main()
{
    std::thread threads[20];
 
    for(auto & a : threads)
    {
        a = std::thread(&child);
    }
    while(1)
    {
        {
            std::unique_lock<std::mutex> lk(foodMutex);
            foodCond.wait(lk, [] { return plums == 0; } ); // ждем пока сливы не кончатся
            plums = 100;
            foodCond.notify_all();
            //std::cout << "Mom added plums" << std::endl;
        }
        //usleep(1000000); 
    }
}
1
22.11.2014, 21:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.11.2014, 21:47
Привет! Вот еще темы с ответами:

Странное поведение вектора при многопоточном обращении - C++
обращаюсь к другому классу из потока, чтобы поискать в векторе: gCacheAVD_mutex.lock(); std::cout &lt;&lt; &quot;this-&gt;cacheAVP.size() = &quot; &lt;&lt;...

Найти ошибки в многопоточном приложении - C#
1 поток- нахождение среднекв.отклонения каждых 1000 элементов 2 поток- сумма каждых ста элементов помогите разобраться, что начудила и...

Ошибки с перерисовкой окна в многопоточном приложении - C++ Qt
Сабж. Есть два окна. При клике на кнопку в одном, вызываем слот второго. В этом слоте запускается новый поток. При этом окна...

Ошибки в вычислении - MathCAD
Нужно вычислить по данным У меня возникает ошибка в переменной d:


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru