Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вернуть значение функции из потока (boost), Помогите разобраться :) 
:(
    Опции темы
correy
Дата 10.10.2013, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Здравствуйте, уже второй день бьюсь над темой. Может быть кто поможет.
У меня есть функция: ComputeSum(vector <wstring> files, int begin, int end), которая проходит вектор от begin до end, подсчитывая определенную сумму. Мне нужно, чтобы каждый из двух потоков пробегал свою часть вектора и возвращал свою сумму, каждую из которых я потом сложу и получу профит! smile

Кто-нибудь поможет?smile
PM MAIL   Вверх
azesmcar
Дата 10.10.2013, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



используй boost::future

PM   Вверх
correy
Дата 10.10.2013, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Именно с этим и требуется помощь smile 
PM MAIL   Вверх
correy
Дата 10.10.2013, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Немного разобрался, получается следующее: 

boost::future <int> s1,s2;
s1 = boost::async(boost::bind(&::ComputeSum,files, begin1, end1));
int sum1 = s1.get();
s2 = boost::async(boost::bind(&::ComputeSum,files, begin2, end2));
int sum2 = s2.get();

Но в данном случае потоки работают последовательно. Или я ошибаюсь? И если я не прав, то как реализовать параллельное выполнение?
PM MAIL   Вверх
azesmcar
Дата 10.10.2013, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



пример на C++11, но в boost он не должен сильно отличаться.
Код

#include <iostream>
#include <vector>
#include <future>
#include <numeric>

int calculate(
    std::vector<int>::iterator begin,
    std::vector<int>::iterator end)
{
    return std::accumulate(begin, end, 0, std::plus<int>());
}

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    std::vector<int>::iterator middle = v.begin() + v.size() / 2;

    std::future<int> result1 = std::async(calculate, v.begin(), middle);
    std::future<int> result2 = std::async(calculate, middle, v.end());

    std::cout << result1.get() + result2.get() << std::endl;
}


Добавлено через 1 минуту и 23 секунды
Цитата(correy @  10.10.2013,  12:42 Найти цитируемый пост)
Но в данном случае потоки работают последовательно. Или я ошибаюсь?

Нет, все верно.
Надо сперва создавать потоки а потом вызывать get(), так-как он блокирует вызов до завершения потока.
PM   Вверх
correy
Дата 10.10.2013, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Спасибо большое за пример!

Т.е. так потоки уже будут работать параллельно?
Код

s1 = boost::async(boost::bind(&::ComputeSum,files, begin1, end1));
s2 = boost::async(boost::bind(&::ComputeSum,files, begin2, end2));
            
wcout << L"sum = " << s1.get()+s2.get();


PM MAIL   Вверх
azesmcar
Дата 10.10.2013, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(correy @  10.10.2013,  12:55 Найти цитируемый пост)
Т.е. так потоки уже будут работать параллельно?

Верно. Вызор get() заблокирует выполнение основного потока до завершения дочерних, но сами дочерние потоки будут работать. А основной будет спать, пока те оба не завершат свою работу и не вернут результат подсчета.
PM   Вверх
correy
Дата 10.10.2013, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Цитата

Верно. Вызор get() заблокирует выполнение основного потока до завершения дочерних, но сами дочерние потоки будут работать. А основной будет спать, пока те оба не завершат свою работу и не вернут результат подсчета. 


Спасибо большое. И еще последний вопрос остался: мне в задании необходимо после каждой итерации суммирования усыплять поток на 1 секунду. Когда я запускаю свою программу, то иногда она просто зависает и не выводит результат. Это как-то может быть связано с усыплением потоков?

Грубо говоря, сейчас все работает через раз smile
PM MAIL   Вверх
correy
Дата 10.10.2013, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Возможно проблема с зависанием возникает, когда оба потока хотят одновременно вывести на экран? Если да, то как корректно организовать работу с мьютексами? Я попробовал так, но получилось не очень smile

Код

if (!wcin.fail())
        {
                
            m.lock();
            wcout << files[begin].data() << L": " << num << endl;                
            sum = sum + num;
            m.unlock();    
        }

PM MAIL   Вверх
bsa
Дата 10.10.2013, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



correy, никогда не сталкивался с проблемой конкурентного вывода на консоль. Максимум, данные идут в разнобой, но ничего не виснет.
Повисания могут происходить из-за ситуации, когда один и тот же мьютекс лочится два раза. Если такой ситуации нет, то возможна более сложная: поток1 лочит мьютекс m1, поток2 лочит мьютекс m2, поток1 пытается залочить m2 и встает в ожидании, поток2 пытается залочить m1 и тоже встает. Выйти из этой ситуации уже нельзя. Надо исправлять код.
PM   Вверх
correy
Дата 10.10.2013, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Цитата

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


Т.е. можно вообще обойтись без использования мьютексов? Т.к. мне кажется, что у меня нет больше ресурсов, за которые эти потоки могут бороться. Тогда непонятна причина зависания :(

Добавлено через 2 минуты и 4 секунды
Вот тут код моей функции:
Код


    wstreambuf *backup = wcin.rdbuf();
    int num;
    int sum=0;
    
    for (;begin <= end; begin++)
    {
        
        wifstream file(files[begin].data());
        wcin.rdbuf(file.rdbuf());
        wcin >> num; 
        
        if (!wcin.fail())
        {
            
            wcout << files[begin].data() << L": " << num << endl;                
            sum = sum + num;            
            
        }
        
        file.close();
        wcin.rdbuf(backup);
                
        Sleep(1000);
    }
    
    return sum;


Не могу понять, в чем может быть проблема(

PM MAIL   Вверх
correy
Дата 10.10.2013, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 1.6.2010

Репутация: нет
Всего: нет



Кажется разобрался, всем спасибо!
PM MAIL   Вверх
bsa
Дата 10.10.2013, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



correy, пожалуйста, всегда пиши как решил проблему. Потому что у кого-то она тоже может возникнуть.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0552 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.