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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
MastAKK
145 / 136 / 12
Регистрация: 13.10.2012
Сообщений: 592
#1

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

03.07.2014, 02:23. Просмотров 1727. Ответов 14
Метки нет (Все метки)

Доброго времени суток.
Подскажите, как запустить несколько независимых потоков, но дождаться, пока все завершатся?
В каждом потоке есть функция 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 независимых потока, которые сортируют. Затем жду завершения и вывожу время выполнения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.07.2014, 02:23
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Запуск нескольких независимых потоков. Дождаться завершения всех (C++ 11) (C++):

Как дождаться завершения потока? - C++
void Thread(void* pParam); void main(){ _beginthread(Thread, 0, NULL);//Запускаем поток, он выполняет свои задачи.... //Тут...

Многопоточность (вычисление корня квадратного уравнения, используя несколько независимых потоков) - C++
Уважаемые программисты! Сможет ли кто-нибудь хотя бы примерно объяснить, как реализовать, например, вычисление корня квадратного уравнения,...

Генерация всех максимальных независимых множеств графа - C++
Здравствуйте,обращаюсь к вам по поводу задания своей курсовой работы по дискретной математике- генерация всех максимальных независимых...

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

Многопоточная программа. Вывод в общий файл из нескольких потоков - C++
Здравствуйте! Ооочень нужна ваша помощь. Необходимо разработать программу, состоящую из 3 потоков. С функцией -последовательный вывод в...

Как сделать чтобы массив заполнился из нескольких потоков? - C++
Задан двумерный массив A из N x N элементов, расположенный в локальной памяти каждой нити, то есть массив A разделен на m одинаковых блоков...

14
gray_fox
What a waste!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
03.07.2014, 04:44 #2
MastAKK, эмм, а thread::join не подходит?
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
03.07.2014, 06:13 #3
Цитата Сообщение от MastAKK Посмотреть сообщение
Как правильно сделать мультипотоковую сортировку?
IMHO - Для таких задач OpenMP покрывает явную организацию потоков как бык овцу.
2
MastAKK
145 / 136 / 12
Регистрация: 13.10.2012
Сообщений: 592
03.07.2014, 12:00  [ТС] #4
gray_fox, так thread::join вроде приостанавливает основной поток до завершения нового?
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
03.07.2014, 12:08 #5
Цитата Сообщение от MastAKK Посмотреть сообщение
gray_fox, так thread::join вроде приостанавливает основной поток до завершения нового?
Нет. Этот метод присоеденяет текущий поток к потоку вызвавшему этот метод в результате чего последний поток ждет его завершения прежде чем завершиться самому.
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
03.07.2014, 12:21 #6
Цитата Сообщение от Ilot Посмотреть сообщение
Этот метод присоеденяет текущий поток к потоку вызвавшему этот метод в результате чего последний поток ждет его завершения прежде чем завершиться самому.
Как-то сумбурно. Что значит "присоеденяет"? Вот первое попавшееся определение:
Blocks the current thread until the thread identified by *this finishes its execution.
отсюда
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
03.07.2014, 12:28 #7
Цитата Сообщение от Tulosba Посмотреть сообщение
ак-то сумбурно. Что значит "присоеденяет"?
Ну да в русском я как енот полоскун в квантовой электродинамике. Скажем так поток ожидает завершения присоедененного потока прежде чем завершиться самому. Момент... суть в том, что основной поток будет выполнять код и после строчки thread::join() т.е. он не приостанавливается, а продолжает выполняться далее пока не встретит точку выхода где и будет ждать завершения присоедененного потока. Как то так.
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
03.07.2014, 12:34 #8
Цитата Сообщение от Ilot Посмотреть сообщение
т.е. он не приостанавливается, а продолжает выполняться далее пока не встретит точку выхода где и будет ждать завершения присоедененного потока. Как то так.
Отнюдь не так. Я же цитату даже привел, где сказано, что происходит блокировка текущего потока.
1
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
03.07.2014, 12:45 #9
Цитата Сообщение от Tulosba Посмотреть сообщение
Отнюдь не так. Я же цитату даже привел, где сказано, что происходит блокировка текущего потока.
Странно всегда думал иначе. Сейчас проверю...

Добавлено через 6 минут
Tulosba, все верно я не прав
0
DiffEreD
1431 / 768 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
03.07.2014, 13:31 #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 Посмотреть сообщение
Как правильно сделать мультипотоковую сортировку?
Вообще, параллельную сортировку очень сложно реализовать. Пример есть в моем блоге.
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
03.07.2014, 14:12 #11
Цитата Сообщение от DiffEreD Посмотреть сообщение
Вообще, параллельную сортировку очень сложно реализовать.
Это если сортировать одну последовательность в несколько потоков. А в исходной постановке:

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

Добавлено через 1 час 26 минут
http://openmp.org/wp/openmp-compilers/
1
gromo
372 / 271 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
04.07.2014, 19:12 #14
uglyPinokkio, просто прагмы не очень хороший стиль
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
04.07.2014, 19:18 #15
Цитата Сообщение от gromo Посмотреть сообщение
просто прагмы не очень хороший стиль
Для того, что бы одной строкой распараллелить вычисления по количеству ядер в среде исполнения, я согласен на некоторый ущерб своему чувству прекрасного.
0
04.07.2014, 19:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.07.2014, 19:18
Привет! Вот еще темы с ответами:

Что является причиной ошибки после завершения всех операций? (динамический массив) - C++
Что является причиной ошибки после завершения всех операций? (динамический массив) #include &lt;iostream&gt; #include &lt;conio.h&gt; #include...

Как дождаться завершения нескольких потоков - Java
Добрый день. Столкнулся с такой проблемой: в методе main() создается n одинаковых потоков, каждый из которых обрабатывает по файлу......

Правильно создать пул потоков, запустить эти потоки одновременно и дождаться их завершения - C#
Добрый день! Подскажите пожалуйста, как правильно создать пул потоков, запустить эти потоки одновременно и дождаться завершения всех...

Можно ли ждать завершения одновременно сразу нескольких потоков? - Python
Можно ли ждать завершения одновременно сразу нескольких потоков или выставления нескольких эвентов ? Нечто вроде аналога...


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

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

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