Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.59/22: Рейтинг темы: голосов - 22, средняя оценка - 4.59
0 / 0 / 0
Регистрация: 15.03.2019
Сообщений: 126

Как запустить многопоточность?

14.07.2021, 10:15. Показов 4518. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, подскажите пожалуйста, как правильно запустить многопоточность не ожидая окончания предыдущего потока?
(run) сделал бесконечным просто для вида, так как у меня там будут функции которые буду пол дня делаться, так что для теста разницы нет.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void run(std::string threadName) {
    while (true)
    {
        cout <<  threadName  + "\n";
    }
        
}
 
 
 
int main()
{
for(int i = 0;i < 5;i++)
{
 
    std::thread tA(run, to_string(i) + "A");
    tA.join();
}
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.07.2021, 10:15
Ответы с готовыми решениями:

Многопоточность: как запустить поток с возможностью остановки и приостановки извне?
Столкнулся с проблемой, что надо запустить поток с возможностью остановки и приостановки из вне (типа команд pause и terminate). Из...

BackgroundWorker. Многопоточность. Как запустить несколько форм?
Имеется - главная форма - &quot;Main.cs&quot;. - форма с &quot;progressBar&quot; - &quot;progressBar.cs&quot; Сценарий: Пользователь. Форма -...

Многопоточность: Открыть форму и, сразу после её открытия, запустить подключение к удалённому серверу
В общем, мне нужно сделать следующее: - открыть форму и, сразу после её открытия, запустить подключение к удалённому серверу; - если...

17
фрилансер
 Аватар для Алексей1153
6440 / 5634 / 1127
Регистрация: 11.10.2019
Сообщений: 14,980
14.07.2021, 11:17
Лучший ответ Сообщение было отмечено Siserian как решение

Решение

Siserian,
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
#include <thread>
#include <vector>
#include <iostream>
 
void run(const std::string threadName)
{
    while (true)
    {
        std::cout <<  threadName  << "\n";
    }
}
 
int main()
{
    std::vector<std::thread> list(5);
    int i=0;
    for(auto& t:list)
    {
        t=std::thread(run, std::to_string(i++) + "A");
    }
 
    for(auto& t:list)
    {
        t.join();
    }
}
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.07.2021, 13:26
Цитата Сообщение от Алексей1153 Посмотреть сообщение
void run(const std::string threadName)
C++
1
void run(const std::string& threadName)
Цитата Сообщение от Алексей1153 Посмотреть сообщение
int i=0;
C++
1
size_t i = 0;
1
фрилансер
 Аватар для Алексей1153
6440 / 5634 / 1127
Регистрация: 11.10.2019
Сообщений: 14,980
14.07.2021, 13:52
hoggy, ссылку на локальный объект передавать в поток ?
0
124 / 44 / 15
Регистрация: 01.11.2020
Сообщений: 122
14.07.2021, 14:30
Алексей1153, по ссылке это std::ref / std::cref
1
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
14.07.2021, 14:31
Алексей1153, оно все равно скопируется. Без std::ref не получится ссылку передать просто так.
2
фрилансер
 Аватар для Алексей1153
6440 / 5634 / 1127
Регистрация: 11.10.2019
Сообщений: 14,980
14.07.2021, 14:40
DrOffset, хм, то есть, я так понял, копия делается принудительно тут

https://en.cppreference.com/w/... ead/thread
Creates new std::thread object and associates it with a thread of execution. The new thread of execution starts executing
std::invoke(decay_copy(std::forward<Func tion>(f)),
decay_copy(std::forward<Args>(args))...);
where decay_copy is defined as

template <class T>
std::decay_t<T> decay_copy(T&& v) { return std::forward<T>(v); }
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.07.2021, 14:53
Цитата Сообщение от Алексей1153 Посмотреть сообщение
ссылку на локальный объект передавать в поток ?
не "локальный", а "временный"
здесь: std::to_string(i++) + "A" создаётся временный объект.

при конструировании объекта-потока:
Цитата Сообщение от Алексей1153 Посмотреть сообщение
t=std::thread(run, std::to_string(i++) + "A");
происходит bind аргумента: std::to_string(i++) + "A"

если совсем простыми словами:
временный объект будет скопированн вовнутрь std::thread
1
фрилансер
 Аватар для Алексей1153
6440 / 5634 / 1127
Регистрация: 11.10.2019
Сообщений: 14,980
14.07.2021, 15:01
Цитата Сообщение от hoggy Посмотреть сообщение
временный
Цитата Сообщение от hoggy Посмотреть сообщение
происходит bind
это всё было известно, но было непонятно, откуда копия берётся. Теперь вроде разобрался
0
0 / 0 / 0
Регистрация: 15.03.2019
Сообщений: 126
14.07.2021, 16:57  [ТС]
как правильно сделать вывод?
Подскажите пожалуйста почему выводится это в консоли?

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
int podgotovka(int potok,int k,int k2)
{
 
    cout << " potok "  << potok << k << " k " << k2 << "k2" << endl;
    return 0;
}
int main()
{
std::vector<std::thread> list(5);
    int i = 0;
    int k = 5;
    int k2 = 150 / 5;
    for (auto& t : list)
    {
        t = std::thread(podgotovka, i++ , k , k2);
        k = k2;
        k2 = k2 + k2;
    }
 
    for (auto& t : list)
    {
        t.join();
    }
 
    return 0;
}
potok potok 4240 k 480k2 potok 260 k 120k2
potok 130 k 60k2
3
potok 05 k 30k2
120 k 240k2
0
124 / 44 / 15
Регистрация: 01.11.2020
Сообщений: 122
14.07.2021, 17:25
Лучший ответ Сообщение было отмечено Siserian как решение

Решение

Siserian, ну так хотели многопоточность - получите

так ?
C++
1
2
3
4
5
6
7
8
9
10
11
#include <sstream>
....
 
 
int podgotovka(int potok,int k,int k2)
{
    std::stringstream ss;
    ss << " potok: "  << potok <<  " k: " << k  << " k2: "<< k2  <<  std::endl;
     std::cout << ss.str();
    return 0;
}
1
0 / 0 / 0
Регистрация: 15.03.2019
Сообщений: 126
28.07.2021, 16:25  [ТС]
Здравствуйте, как постоянно дополнять потоки которые закончили свою задачу?
т.е. когда из 5 потоков хоть 1 закончит свою работу, что бы через цикл for ему далось следующее число, и отправил в работу.
т.е. что бы ядра были всегда загружены на 100% ( разбиваю 1 задачу на 100 маленьких)
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
#include <thread>
#include <vector>
#include <iostream>
 
void run(const std::string threadName,int job)
{
    while (true)
    {
        std::cout <<  threadName  << "\n";
    }
}
 
int main()
{
    std::vector<std::thread> list(5);
    int i=0;
for(int job = 0; job < 100; job++)    // знаю что это не так делается :D , эт просто что бы было понятнее....
  {
    for(auto& t:list)
    {
        t=std::thread(run, std::to_string(i++) + "A",job);
    }
 
    for(auto& t:list)
    {
        t.join();
    }
 }
}
0
736 / 700 / 110
Регистрация: 29.05.2015
Сообщений: 4,260
28.07.2021, 21:24
Я пошёл по самому простому пути: по нажатию кнопки создаётся новый поток,

C++ (Qt)
1
2
    pp_00 = new potok(x_inp);
    pp_00->start();
в него через конструктор передаётся информация (число), поток отрабатывает (проверяет на простоту, если число не простое - берёт следующее и так далее, пока не найдёт простое), посылает сигнал с найденным числом, и заканчивает своё существование оператором "exec();" - по крайней мере я думаю, что заканчивает. При следующем нажатии кнопки всё повторяется.

Это работает, что-бы на время работы потока разгрузить GUI - но по моему разумению плохо подходит совсем не подходит для многопоточных вычислений. Там не нужно каждый раз создавать/убивать потоки. Поток должен получать (сигналом?) задание, выполнять его, отправлять сигналом результат, и становиться на паузу до получения нового задания. Так?
0
124 / 44 / 15
Регистрация: 01.11.2020
Сообщений: 122
28.07.2021, 21:51
Цитата Сообщение от Siserian Посмотреть сообщение
Здравствуйте как постоянно дополнять потоки которые закончили свою задачу?
Здравствуйте.
я бы взял какую-нибудь готовую реализацию thread pool
0
0 / 0 / 0
Регистрация: 15.03.2019
Сообщений: 126
29.07.2021, 10:06  [ТС]
Цитата Сообщение от alexu_007 Посмотреть сообщение
Это работает, что-бы на время работы потока разгрузить GUI - но по моему разумению плохо подходит совсем не подходит для многопоточных вычислений. Там не нужно каждый раз создавать/убивать потоки. Поток должен получать (сигналом?) задание, выполнять его, отправлять сигналом результат, и становиться на паузу до получения нового задания. Так?
да нет, вот просто есть цикл который отдаёт в потоки от 0 до 2000 числа с прибавлением +=2.
потоков всего 5(условно)
и мне нужно что бы когда 1 потом доделал свою микроработу и сдох, что бы цикр запустил следующий поток с другим числом.

Добавлено через 2 минуты
Цитата Сообщение от stepForward Посмотреть сообщение
Здравствуйте.
я бы взял какую-нибудь готовую реализацию thread pool
нашел на просторах сией код, как я понимаю он сойдёт!?
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
// synchronized output to prevent interleaving of results
#define sync_out(m) do{std::ostringstream o; o << m << '\n'; std::cout << o.str();}while(0)
 
void someJob(int id)
{
    sync_out("thread: " << id);
}
 
template<typename Job>
void start_thread(std::vector<std::thread>& threads, Job&& job)
{
    // find an ended thread
    for(auto&& thread: threads)
    {
        if(thread.joinable()) // still running or waiting to join
            continue;
 
        thread = std::thread(job);
        return;
    }
 
    // if not wait for one
    for(auto&& thread: threads)
    {
        if(!thread.joinable()) // dead thread (not run or already joined)
            continue;
 
        thread.join();
        thread = std::thread(job);
        return;
    }
}
 
int main()
{
 
    std::vector<std::thread> threads(5); // 5 threads
 
    for(int i = 0; i < 100; i++)
        start_thread(threads, [=]{someJob(i);});
 
    // wait for any unfinished threads    
    for(auto&& thread: threads)
        if(thread.joinable())
            thread.join();
}
0
фрилансер
 Аватар для Алексей1153
6440 / 5634 / 1127
Регистрация: 11.10.2019
Сообщений: 14,980
29.07.2021, 10:16
Цитата Сообщение от Siserian Посмотреть сообщение
auto&&
здесь лучше просто ссылку
auto&

Цитата Сообщение от Siserian Посмотреть сообщение
thread = std::thread(job);
тут забыт форвард
thread = std::thread(std::forward<Job>(job));
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
29.07.2021, 12:14
Цитата Сообщение от Siserian Посмотреть сообщение
// synchronized output to prevent interleaving of results
#define sync_out(m) do{std::ostringstream o; o << m << '\n'; std::cout << o.str();}while(0)
код взят со стек-оверфлоу.
код некорректен.

стандарт не даёт никаких оснований думать,
что методы operator<< являются thread-safe
про синхронизацию я вообще молчу.

рекомендую к прочтению ещё одну ссылку на стек-оверфлоу.


зы:
во времена до с++11,
ни о каком thread-safe даже речи не шло,
потому что ещё самого понятия такого не было.
язык признал существование потоков только начиная с эпохи с++11.

начиная с с++11,
стандарт по прежнему не даёт никаких специальных гарантий.
смотреть нужно на гарантии,
которые предоставляют конкретные реализации.

как правило,
реализации обеспечивают thread-safe,
но не обеспечивают synchronized.
это означает, что вызывать operator<< из разных потоков можно (UB не случится),
но буковки от разных потоков могут перемешиваться,
как это и произошло у парня, по ссылке выше.
то есть, в результате можно получить кашу.

поэтому,
необходимо использовать внешнию синхронизацию.

начиная с с++20,
в стандарт наконец то завезли специализированный osyncstream

если у тебя в 2021 году уже поддерживается с++20,
тогда osyncstream - то, что доктор прописал.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
29.07.2021, 17:04
Лучший ответ Сообщение было отмечено Siserian как решение

Решение

Цитата Сообщение от Siserian Посмотреть сообщение
Здравствуйте, как постоянно дополнять потоки которые закончили свою задачу?
т.е. когда из 5 потоков хоть 1 закончит свою работу, что бы через цикл for ему далось следующее число, и отправил в работу.
т.е. что бы ядра были всегда загружены на 100% ( разбиваю 1 задачу на 100 маленьких)
потоки не должны завершать работу, пока все числа не будут обработаны.
Должен быть контейнер с числами(и мьютекс, синхронизтрующий доступ к нему)
Каждый поток должен в цикле брать 1 или несколько чисел из контейнера, работать с ними и завершаться, когда контейнер станет пуст.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.07.2021, 17:04
Помогаю со студенческими работами здесь

Многопоточность, как?
Покажите как правильно реализовать, пробовал сам разобраться, мозгов нехватило. private: System::Void...

Как запустить в JS запустить код батника без создания самого батника?
Запуск процесса cmd.exe в js делаю вот так: native_async(&quot;processmanager&quot;, &quot;start&quot;, JSON.stringify({location: &quot;cmd.exe&quot;,...

Как поддерживать многопоточность?
Есть восьмиядерный процессор, у которого 7 ядер из восьми делают вид, что работают. А на самом деле нет. Вот создаём 8 нитей...

Как создать многопоточность
В сети гуглил, но так банального ответа для себя не нашёл, как размногопоточить приложение, в delphi делал так function getnumberbux:...

Как реализуется многопоточность в VB?
Подскажите плз как реализуется многопоточность в VB, если конечно здесь таковая имеется.


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru