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

Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) - C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
MastAKK
 Аватар для MastAKK
144 / 135 / 12
Регистрация: 13.10.2012
Сообщений: 586
Записей в блоге: 1
03.07.2014, 02:23     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #1
Доброго времени суток.
Подскажите, как запустить несколько независимых потоков, но дождаться, пока все завершатся?
В каждом потоке есть функция bool sort(int** matrix, int row), которая рекурсивно вызывает себя, передавая матрицу и номер строки с шагом в количество потоков.
Размер матрицы - глобальная константа size.
Использую std::future
Пытался ожидать, пока все потоки вернут true (std::future::get()), но тогда программы выполняется с той же скоростью, что и в одном потоке.
Если ожидать возвращение true только от последнего потока - массив не всегда отсортирован (что вполне логично).
Как правильно сделать мультипотоковую сортировку? Как дождаться завершения всех потоков?

Чуть подробнее

Есть простая программа для сортировки матрицы.
Имеются 3 константы:
C++
1
2
const int thrCount = 4;//кол-во потоков
const int size = 100; //размер матрицы AxA
И матрица
C++
1
int matrix[size][size];
Которую я заполняю случайными числами.
Затем создаются 4 независимых потока, которые сортируют. Затем жду завершения и вывожу время выполнения.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.07.2014, 02:23     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11)
Посмотрите здесь:

C++ Структуры. По запросу выдать: всех женщин, сменивших свою фамилию, всех военнообязанных, всех холостых
Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) C++
Что является причиной ошибки после завершения всех операций? (динамический массив) C++
Как дождаться завершения потока? C++
Генерация всех максимальных независимых множеств графа C++
C++ Создание и завершение процессов и потоков. Приоритеты выполнения потоков
C++ Запуск и последующее удаление всех исполняемых файлов из каталога
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1246 / 1129 / 54
Регистрация: 21.04.2012
Сообщений: 2,354
Завершенные тесты: 3
03.07.2014, 04:44     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #2
MastAKK, эмм, а thread::join не подходит?
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
03.07.2014, 06:13     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #3
Цитата Сообщение от MastAKK Посмотреть сообщение
Как правильно сделать мультипотоковую сортировку?
IMHO - Для таких задач OpenMP покрывает явную организацию потоков как бык овцу.
MastAKK
 Аватар для MastAKK
144 / 135 / 12
Регистрация: 13.10.2012
Сообщений: 586
Записей в блоге: 1
03.07.2014, 12:00  [ТС]     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #4
gray_fox, так thread::join вроде приостанавливает основной поток до завершения нового?
Ilot
Модератор
Эксперт С++
1778 / 1153 / 223
Регистрация: 16.05.2013
Сообщений: 3,042
Записей в блоге: 5
Завершенные тесты: 1
03.07.2014, 12:08     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #5
Цитата Сообщение от MastAKK Посмотреть сообщение
gray_fox, так thread::join вроде приостанавливает основной поток до завершения нового?
Нет. Этот метод присоеденяет текущий поток к потоку вызвавшему этот метод в результате чего последний поток ждет его завершения прежде чем завершиться самому.
Tulosba
:)
Эксперт С++
4382 / 3225 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
03.07.2014, 12:21     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #6
Цитата Сообщение от Ilot Посмотреть сообщение
Этот метод присоеденяет текущий поток к потоку вызвавшему этот метод в результате чего последний поток ждет его завершения прежде чем завершиться самому.
Как-то сумбурно. Что значит "присоеденяет"? Вот первое попавшееся определение:
Blocks the current thread until the thread identified by *this finishes its execution.
отсюда
Ilot
Модератор
Эксперт С++
1778 / 1153 / 223
Регистрация: 16.05.2013
Сообщений: 3,042
Записей в блоге: 5
Завершенные тесты: 1
03.07.2014, 12:28     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #7
Цитата Сообщение от Tulosba Посмотреть сообщение
ак-то сумбурно. Что значит "присоеденяет"?
Ну да в русском я как енот полоскун в квантовой электродинамике. Скажем так поток ожидает завершения присоедененного потока прежде чем завершиться самому. Момент... суть в том, что основной поток будет выполнять код и после строчки thread::join() т.е. он не приостанавливается, а продолжает выполняться далее пока не встретит точку выхода где и будет ждать завершения присоедененного потока. Как то так.
Tulosba
:)
Эксперт С++
4382 / 3225 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
03.07.2014, 12:34     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #8
Цитата Сообщение от Ilot Посмотреть сообщение
т.е. он не приостанавливается, а продолжает выполняться далее пока не встретит точку выхода где и будет ждать завершения присоедененного потока. Как то так.
Отнюдь не так. Я же цитату даже привел, где сказано, что происходит блокировка текущего потока.
Ilot
Модератор
Эксперт С++
1778 / 1153 / 223
Регистрация: 16.05.2013
Сообщений: 3,042
Записей в блоге: 5
Завершенные тесты: 1
03.07.2014, 12:45     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #9
Цитата Сообщение от Tulosba Посмотреть сообщение
Отнюдь не так. Я же цитату даже привел, где сказано, что происходит блокировка текущего потока.
Странно всегда думал иначе. Сейчас проверю...

Добавлено через 6 минут
Tulosba, все верно я не прав
DiffEreD
 Аватар для DiffEreD
1424 / 761 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
03.07.2014, 13:31     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #10
Цитата Сообщение от MastAKK Посмотреть сообщение
Как дождаться завершения всех потоков?
Можно вылавливать на future готовые результаты в цикле. Результаты будем получать в порядку завершения потоков. Вот надуманный пример:
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
52
53
54
#include <iostream>
#include <vector>
#include <algorithm>
#include <future>
#include <thread>
#include <chrono>
 
int main()
{
   using fut_t = std::future<int>;
   std::vector<fut_t> futures;
 
   auto is_future_valid = [](fut_t& fut)
   {
      return fut.valid();
   };
   auto is_future_ready = [&is_future_valid](fut_t& fut)
   {
      return is_future_valid(fut) && fut.wait_for(
               std::chrono::microseconds(100)) == std::future_status::ready;
   };
 
   futures.emplace_back(std::async(std::launch::async, []{
      std::this_thread::sleep_for(std::chrono::seconds(5));
      return 1;
   }));
 
   futures.emplace_back(std::async(std::launch::async, []{
      std::this_thread::sleep_for(std::chrono::seconds(15));
      return 2;
   }));
 
   futures.emplace_back(std::async(std::launch::async, []{
      std::this_thread::sleep_for(std::chrono::seconds(10));
      return 3;
   }));
 
   futures.emplace_back(std::async(std::launch::async, []{
      std::this_thread::sleep_for(std::chrono::seconds(3));
      return 42;
   }));
 
   while (std::any_of(futures.begin(), futures.end(), is_future_valid)) {
      auto next = std::find_if(futures.begin(), futures.end(), is_future_ready);
      if (next == futures.end())
      {
         continue;
      }
 
      std::cout << next->get() << std::endl;
   }
 
   return 0;
}
Добавлено через 3 минуты
Цитата Сообщение от MastAKK Посмотреть сообщение
Как правильно сделать мультипотоковую сортировку?
Вообще, параллельную сортировку очень сложно реализовать. Пример есть в моем блоге.
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
03.07.2014, 14:12     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #11
Цитата Сообщение от DiffEreD Посмотреть сообщение
Вообще, параллельную сортировку очень сложно реализовать.
Это если сортировать одну последовательность в несколько потоков. А в исходной постановке:

Цитата Сообщение от MastAKK Посмотреть сообщение
Подскажите, как запустить несколько независимых потоков, но дождаться, пока все завершатся?
В каждом потоке есть функция bool sort(int** matrix, int row), которая рекурсивно вызывает себя, передавая матрицу и номер строки с шагом в количество потоков.
Это делается одной строкой.
C++
1
   #pragma omp parallel for
gromo
 Аватар для gromo
367 / 266 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
04.07.2014, 00:46     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #12
uglyPinokkio, а ваша одна строка будет везде работать? Сомневаюсь
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
04.07.2014, 06:56     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #13
Цитата Сообщение от gromo Посмотреть сообщение
а ваша одна строка будет везде работать? Сомневаюсь
Естественно, работать она будет для компиляторов, поддерживающих OpenMP. ms и gcc на linux и windows поддерживают.

Добавлено через 1 час 26 минут
http://openmp.org/wp/openmp-compilers/
gromo
 Аватар для gromo
367 / 266 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
04.07.2014, 19:12     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #14
uglyPinokkio, просто прагмы не очень хороший стиль
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.07.2014, 19:18     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11)
Еще ссылки по теме:

Код завершения процесса C++
Создать множество независимых объектов, подобных танкам в игре Battle City C++
Вывод в консоль из нескольких потоков C++
Если не вводится число, то закрыть ввод и дождаться конца программы C++
C++ Запуск нескольких раз программы для работы со строкой

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

Или воспользуйтесь поиском по форуму:
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
04.07.2014, 19:18     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) #15
Цитата Сообщение от gromo Посмотреть сообщение
просто прагмы не очень хороший стиль
Для того, что бы одной строкой распараллелить вычисления по количеству ядер в среде исполнения, я согласен на некоторый ущерб своему чувству прекрасного.
Yandex
Объявления
04.07.2014, 19:18     Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11)
Ответ Создать тему
Опции темы

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