Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/16: Рейтинг темы: голосов - 16, средняя оценка - 5.00
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313

Std::thread. Нет ожидаемого поведения при независимом вычислении элементов вектора

04.12.2017, 08:44. Показов 3620. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хочу распараллелить вычисления отдельных элементов массива: каждый - в своём потоке.
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <iomanip>
#include <vector>
#include <thread>
#include <atomic>
using namespace std;
 
template <class T>
ostream& operator<< (ostream& out, vector<T> const& v) {
    for(auto const& x: v)
        out << setw(5) << x << ' ';
    return out;
}
 
void f(int& x, atomic<size_t>& count_results, size_t i) {
    for(size_t j = 0; j <= i; ++j)
        x = x + 1;
    ++count_results;
}
 
void g() {
    vector<int> v(10, 0);
    
    atomic<size_t> count_results = 0;
    for(size_t i = 0; i != 10; ++i)
        thread(f, ref(v[i]), ref(count_results), i).detach();
    
    while(count_results != 10)
        this_thread::yield();
    
    cout << v << endl;
}
 
int main() {
    
    for(size_t k = 1; k <= 100; ++k) {
        cout << "Step " << setw(3) << k << ": ";
        g();
    }
    
    return 0;
}


Проблема в том, что, как мне кажется, не всякий раз поток можно запустить.
Когда я говорю detach(), то в какой-то проход хотя бы один из потоков не запустится,
из-за чего главный поток всё время будет ожидать увеличения счётчика количества выполненной работы.

Как с этим бороться? Что нужно добавить для ожидаемого поведения?
Миниатюры
Std::thread. Нет ожидаемого поведения при независимом вычислении элементов вектора  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.12.2017, 08:44
Ответы с готовыми решениями:

Ошибка при вычислении вектора
Er=5.5; E=0:10; K=1.38*10.^-23; T=50; KT_J=K*T; KT_eV=KT_J/1.6*10.^-19; i=E-Er; I=i/KT_eV; s=exp(I); S=1/s;

Ошибка при создании потока std::thread
Внутри класса есть функция void move(); Нужно, чтобы она работала в отдельном потоке. Проблема : неправильно указываю параметры....

Программа падает при использовании std::thread
Дополнительный вопрос:почему эта программа падает: #include &lt;thread&gt; #include &lt;Windows.h&gt; void client(int arg){ } int main() { ...

25
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
04.12.2017, 23:09
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Lyosha12 Посмотреть сообщение
одновременно для всех объектов?
По порядку. Зачем join() одновременно запускать?
0
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
04.12.2017, 23:50  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Зачем join() одновременно запускать?
Цитата Сообщение от Lyosha12 Посмотреть сообщение
Какой смысл в последовательном исполнении, если операции не зависимы?
Цитата Сообщение от Lyosha12 Посмотреть сообщение
Я матрицы умножаю: умножение каждой строки матрицы A на матрицу B в отдельном потоке.
Как уж изъясняться, что я хочу и музыку слушать, и по улице гулять?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
05.12.2017, 00:00
Лучший ответ Сообщение было отмечено Lyosha12 как решение

Решение

Ты плохо понимаешь как thread работает. Сначала создаёшь потоки, они начинают работать и join() никак этому не мешает, если не делать так, как у тебя - вызов сразу от временного объекта. Ты создал, к примеру, два потока, они начали работу, а после делаешь:
C++
1
2
th1.join();
th2.join();
1
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,430
05.12.2017, 04:08
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
template <class T>
ostream& operator<< (ostream& out, const vector<T>& v) 
{
    for (const auto& x : v)
        out << x << ' ';
    return out;
}
 
void f(vector <int>& v, const size_t beg, const size_t end, const int j)
{
    for (size_t i = beg; i < end; ++i)
        v[i] += j;
}
 
int main() 
{
    vector <int> v(30, 0);
    
    vector <thread> vthr;
    
    int i = 1;
    size_t beg = 0;
    const size_t n = 10;
    size_t end = beg + n;
    for (int j = 0; j < 3; ++j)
    {
        vthr.push_back(thread(f, ref(v), beg, end, i++));
        
        beg = end;
        end += n;
    }
    
    for (auto& thr : vthr)
        thr.join();
 
    cout << v << endl;
        
    system("pause");
    return 0;
}
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
05.12.2017, 07:25
Цитата Сообщение от jahdjkhasjdhjah Посмотреть сообщение
ваша реализация библиотеки не поддерживает такого количества потоков.
когда это стандартная библиотека начала определять кол-во возможных потоков?
0
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
06.12.2017, 18:27  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Ты плохо понимаешь как thread работает. Сначала создаёшь потоки, они начинают работать и join() никак этому не мешает, если не делать так, как у тебя - вызов сразу от временного объекта.
Благодарю за пояснение. Проверил - верно. Поставил Cygwin - всё работает, всё в норме.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.12.2017, 18:27

Ошибка при передаче двумерного массива в функцию std::thread
Здравствуйте! Написал программу на потоки, теперь нужно передать туда двумерный массив. Пытаюсь передать по ссылке, но каждый раз...

Использование std::function в std::thread
Нужно вызвать function fnc в новом потоке. Как сделать? function &lt;void(vector&lt;char&gt;)&gt; fnc; void test(vector&lt;char&gt; data) { ...

Ошибка компиляции "no instance of constructor 'std::thread::thread' matches the argument list"
Не могу сообразить почему возникает ошибка. У меня в классе есть метод, который должен работать в нескольких потоках одновременно. Вот он: ...

Boost::thread std::thread
чем отличается boost::thread( ) от std::thread (с++17)? я спрашиваю не о способе реализации потоков в целом, а конкретно о этих функциях....

Boost::thread vs std::thread
Доброго времени суток, решил углубить свои знания, и решил почитать про потоки, бустовые и те что в 11 стандарте приняли, с бустом все ясно...


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

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru