Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313

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

04.12.2017, 08:44. Показов 3628. Ответов 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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302 Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru