19 / 15 / 7
Регистрация: 27.02.2012
Сообщений: 742
1

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

22.11.2014, 18:41. Показов 515. Ответов 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.11.2014, 18:41
Ответы с готовыми решениями:

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

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

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

Ошибки при вычислении
Что я опять не так делаю? :wall: В методичке тоже самое написано и все вычислено а у меня не...

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

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

20 потоков детей, которые кушают 100 слив по очереди (спасибо мьютексу) и 1 поток мамы, которая восполняет миску сливами в полном объеме. Фактически: декремент объекта класса и по достижении 0 - переинициализация 100.
0
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
22.11.2014, 19:24 6
Ну и где у тебя это? Где 20 потоков создаётся? Там какой-то бесконечный цикл и цикл до food.
0
19 / 15 / 7
Регистрация: 27.02.2012
Сообщений: 742
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
119 / 141 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
22.11.2014, 19:37 8
бесконечный цикл на строчках 4 и 5, который порождает миллионы и дохренилионы потоков
0
19 / 15 / 7
Регистрация: 27.02.2012
Сообщений: 742
22.11.2014, 19:41  [ТС] 9
Цитата Сообщение от demmax2004 Посмотреть сообщение
бесконечный цикл на строчках 4 и 5, который порождает миллионы потоков
Массив потоков объявлен, их 20, а бесконечный цикл направлен на постоянное повторение действий (ребёнок 1...n взял(и) сливу-> если сливы закончились, мама принесла ещё), правильней, конечно задержку поставить секунд в 5, чтобы не выполнялись очень быстро...
0
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
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
19 / 15 / 7
Регистрация: 27.02.2012
Сообщений: 742
22.11.2014, 19:49  [ТС] 11
Цитата Сообщение от nmcf Посмотреть сообщение
void mother()
{
* * coven += 100;
}
маме надлежит возвращать значение в вызов и детям количество оставшихся слив тоже... под мьютекс загнать --coven и джойны в различных циклах, это мне пожалуй надо поправить, вдруг от этого виснет...
0
7166 / 6141 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
22.11.2014, 19:56 12
Зачем возвращать? Это часть задания?
0
19 / 15 / 7
Регистрация: 27.02.2012
Сообщений: 742
22.11.2014, 20:22  [ТС] 13
Цитата Сообщение от nmcf Посмотреть сообщение
Зачем возвращать? Это часть задания?
Нет, но как сделать нечто подобное циклически?

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

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

Добавлено через 19 минут
Переделал и заработало с 1 "НО": 20 детей-потоков, а слив 100, они по одной взяли и наелись...остальные 80 лежат, как разрешить недоразумение, сгниют же?
0
16094 / 8692 / 2124
Регистрация: 30.01.2014
Сообщений: 14,985
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.11.2014, 21:47
Помогаю со студенческими работами здесь

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

Ошибки при вычислении выражения
Помогите почему не работает #include&lt;conio.h&gt; #include&lt;math.h&gt; #include&lt;stdio.h&gt; int main()...

Ошибки при вычислении интегралов
Здравствуйте! Решаю следующую задачу по тер вер.: есть совместная плотность случайных величин...

Исправить ошибки в вычислении выражения
program WHIL uses CRT; var a,b,k:real; n:integer; begin; a:=pi/4; ...

Ошибки при вычислении в double
При выполнении самых простых операций над числами происходит непонятно что. double k = 14.02 -...

Ошибки при вычислении выражения
Народ, я в затупке, что я не так делаю вот код Public Class Form1 Private Sub...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru