С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/56: Рейтинг темы: голосов - 56, средняя оценка - 4.55
148 / 139 / 18
Регистрация: 13.10.2012
Сообщений: 592
1

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

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

Author24 — интернет-сервис помощи студентам
Доброго времени суток.
Подскажите, как запустить несколько независимых потоков, но дождаться, пока все завершатся?
В каждом потоке есть функция 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.07.2014, 02:23
Ответы с готовыми решениями:

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

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

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

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

14
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
03.07.2014, 04:44 2
MastAKK, эмм, а thread::join не подходит?
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
03.07.2014, 06:13 3
Цитата Сообщение от MastAKK Посмотреть сообщение
Как правильно сделать мультипотоковую сортировку?
IMHO - Для таких задач OpenMP покрывает явную организацию потоков как бык овцу.
2
148 / 139 / 18
Регистрация: 13.10.2012
Сообщений: 592
03.07.2014, 12:00  [ТС] 4
gray_fox, так thread::join вроде приостанавливает основной поток до завершения нового?
0
Эксперт по математике/физикеЭксперт С++
2206 / 1411 / 411
Регистрация: 16.05.2013
Сообщений: 3,597
Записей в блоге: 6
03.07.2014, 12:08 5
Цитата Сообщение от MastAKK Посмотреть сообщение
gray_fox, так thread::join вроде приостанавливает основной поток до завершения нового?
Нет. Этот метод присоеденяет текущий поток к потоку вызвавшему этот метод в результате чего последний поток ждет его завершения прежде чем завершиться самому.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2014, 12:21 6
Цитата Сообщение от Ilot Посмотреть сообщение
Этот метод присоеденяет текущий поток к потоку вызвавшему этот метод в результате чего последний поток ждет его завершения прежде чем завершиться самому.
Как-то сумбурно. Что значит "присоеденяет"? Вот первое попавшееся определение:
Blocks the current thread until the thread identified by *this finishes its execution.
отсюда
0
Эксперт по математике/физикеЭксперт С++
2206 / 1411 / 411
Регистрация: 16.05.2013
Сообщений: 3,597
Записей в блоге: 6
03.07.2014, 12:28 7
Цитата Сообщение от Tulosba Посмотреть сообщение
ак-то сумбурно. Что значит "присоеденяет"?
Ну да в русском я как енот полоскун в квантовой электродинамике. Скажем так поток ожидает завершения присоедененного потока прежде чем завершиться самому. Момент... суть в том, что основной поток будет выполнять код и после строчки thread::join() т.е. он не приостанавливается, а продолжает выполняться далее пока не встретит точку выхода где и будет ждать завершения присоедененного потока. Как то так.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.07.2014, 12:34 8
Цитата Сообщение от Ilot Посмотреть сообщение
т.е. он не приостанавливается, а продолжает выполняться далее пока не встретит точку выхода где и будет ждать завершения присоедененного потока. Как то так.
Отнюдь не так. Я же цитату даже привел, где сказано, что происходит блокировка текущего потока.
1
Эксперт по математике/физикеЭксперт С++
2206 / 1411 / 411
Регистрация: 16.05.2013
Сообщений: 3,597
Записей в блоге: 6
03.07.2014, 12:45 9
Цитата Сообщение от Tulosba Посмотреть сообщение
Отнюдь не так. Я же цитату даже привел, где сказано, что происходит блокировка текущего потока.
Странно всегда думал иначе. Сейчас проверю...

Добавлено через 6 минут
Tulosba, все верно я не прав
0
1458 / 795 / 257
Регистрация: 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
327 / 230 / 55
Регистрация: 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
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
04.07.2014, 00:46 12
uglyPinokkio, а ваша одна строка будет везде работать? Сомневаюсь
0
327 / 230 / 55
Регистрация: 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
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
04.07.2014, 19:12 14
uglyPinokkio, просто прагмы не очень хороший стиль
0
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
04.07.2014, 19:18 15
Цитата Сообщение от gromo Посмотреть сообщение
просто прагмы не очень хороший стиль
Для того, что бы одной строкой распараллелить вычисления по количеству ядер в среде исполнения, я согласен на некоторый ущерб своему чувству прекрасного.
0
04.07.2014, 19:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.07.2014, 19:18
Помогаю со студенческими работами здесь

Ожидание завершения всех потоков
Здравствуйте! Помогите, пожалуйста! В отдельных задачах (потоках далее) выполняются какие-то...

Завершения приложения и заверщения всех потоков
Как завершить приложения (как Process.Kill) и как завершить потоки все не имея ссылки на них

Как подождать завершения нескольких потоков, и если после минуты не завершились продолжать выполнение?
Как подождать завершения нескольких потоков, и если после минуты не завершились продолжать...

Запуск нескольких потоков
По отдельности каждый поток запускается, как мне сделать так, чтобы при нажатии кнопки 1 у меня...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru