Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Satansoft
 Аватар для Satansoft
7 / 7 / 1
Регистрация: 27.02.2012
Сообщений: 694
22.11.2014, 18:41     Ошибки в многопоточном вычислении средствами с++11 #1
Задачка:
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. На этапе выполнения программа зависает.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nmcf
4296 / 3717 / 1251
Регистрация: 14.04.2014
Сообщений: 14,536
22.11.2014, 18:46     Ошибки в многопоточном вычислении средствами с++11 #2
mutex должен быть общий для всех потоков, а ты его в каком-то одном объявил.
Satansoft
 Аватар для Satansoft
7 / 7 / 1
Регистрация: 27.02.2012
Сообщений: 694
22.11.2014, 18:52  [ТС]     Ошибки в многопоточном вычислении средствами с++11 #3
Цитата Сообщение от nmcf Посмотреть сообщение
mutex должен быть общий для всех потоков, а ты его в каком-то одном объявил.
Допустим, вынес его в верх секции public, хоть и взаимодействует с массивом потоков, которые получают доступ только к Dinner_a(), в котором он был объявлен локально. Ошибка точно не в этом, она по прежнему виснет, скорее всего где-то на возвращаемых значениях, или счетчик не считает и из-за бесконечного цикла виснет, но не вижу где...
nmcf
4296 / 3717 / 1251
Регистрация: 14.04.2014
Сообщений: 14,536
22.11.2014, 19:02     Ошибки в многопоточном вычислении средствами с++11 #4
Ты пойми, что использованием "карманного" mutex'а, объявленного в самой функции бессмысленно.

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

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

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

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

Добавлено через 19 минут
Переделал и заработало с 1 "НО": 20 детей-потоков, а слив 100, они по одной взяли и наелись...остальные 80 лежат, как разрешить недоразумение, сгниют же?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.11.2014, 21:47     Ошибки в многопоточном вычислении средствами с++11
Еще ссылки по теме:

C++ Факториал в вычислении элемента функции
C++ Странное поведение вектора при многопоточном обращении
Ошибка в вычислении разности матриц C++

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

Или воспользуйтесь поиском по форуму:
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
22.11.2014, 21:47     Ошибки в многопоточном вычислении средствами с++11 #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); 
    }
}
Yandex
Объявления
22.11.2014, 21:47     Ошибки в многопоточном вычислении средствами с++11
Ответ Создать тему
Опции темы

Текущее время: 23:26. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru