Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811

Уведомления между потоками

29.07.2015, 11:35. Показов 4289. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Набросал код для экспериментов:
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
#include "stdafx.h"
 
int блок_1(HWND *hWnd, MyStruct* strukt_1);
int сервис_1(HWND *hWnd, MyStruct* strukt_1);
 
void блок(HWND *hWnd, MyStruct* strukt_1)//запускаем основной поток
{
    int q = 0;
    do
    {
        std::thread potok_блок_1(блок_1, hWnd, strukt_1);
        potok_блок_1.detach();//отсоединение потока
        std::thread potok_сервис_1(сервис_1, hWnd, strukt_1);
        potok_сервис_1.detach();//отсоединение потока
        ++q;
    }
    while ( q != 9 );
}
 
int блок_1(HWND *hWnd, MyStruct* strukt_1)//поток подключения
{   
    do
    {
        Sleep(1000);//10 сек
        (*strukt_1).a = 0;
    }
    while ( true );
    return 0;
}
 
int сервис_1(HWND *hWnd, MyStruct* strukt_1)//поток подключения
{
    do
    {
        Sleep(10);
        
    }
    while ( (*strukt_1).a != 0 );
    return 0;
}
Смысл такой, запускаю 20 фоновых потоков. теперь после каких-то вычислений какой либо из потоков блок_1 изменяет состояние в структуре. А в потоках сервис_1 жду этого изменения в цикле время от времени проверяя... Так вот вопрос в том, как избавится от этих циклов? чтобы не грузить систему. А остановить поток пока не будет сделано изменений в потоке блок_1.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
29.07.2015, 11:35
Ответы с готовыми решениями:

Передача данных между потоками
Есть сервер. Для каждого клиента он создает новый поток и работает с ними независимо от остальных...Например мне надо чтобы получив...

Обмен данными через указатель между потоками
Скажите, валидный ли такой код : #include <iostream> #include <thread> using namespace std; void thread_function(int...

Инкремент переменной между потоками без atomic, с использованием mutex
Есть такой код: #include <iostream> #include <mutex> #include <thread> std::mutex mu;

24
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
29.07.2015, 12:03
Используйте условные переменные. На вашем псевдокоде и по одному потоку для блока и сервиса код будет выглядеть вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::mutex m;
std::condition_variable cv;
int блок_1(HWND *hWnd, MyStruct* strukt_1)//поток подключения
{   
    prepare_data();//<-готовим данные
    cv.notify_one();
    return 0;
}
 
int сервис_1(HWND *hWnd, MyStruct* strukt_1)//поток подключения
{
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, []() { return (*strukt_1).a == 0;});
    do_proccesing(); //<-выполняем, что нужно
    return 0;
}
Что бы более конкретно ответить на вопрос о синхронизации нужно знать больше о том как должны взаимодействовать между собой потоки.
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
29.07.2015, 12:06
Ну это не по языку вопрос а по платформе, для которой этот код предназначен.
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
29.07.2015, 12:10
Цитата Сообщение от Praktolock Посмотреть сообщение
Ну это не по языку вопрос а по платформе, для которой этот код предназначен.
Библиотека С++ (в разделе которого мы находимся ) кроссплатформена.
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
29.07.2015, 12:23  [ТС]
C++
1
cv.wait(lk, []() { return (*strukt_1).a == 0;});
здесь выдает 2 ошибки:

Ошибка C3493 "strukt_1" нельзя передать неявно, поскольку не задан режим передачи по умолчанию Win32Project1 c:\users\admin1\documents\visual studio 2015\projects\win32project1\win32project 1\блок_.cpp 37

Ошибка IntelliSense: на локальную переменную со вложенной функцией нельзя ссылаться внутри тела лямбды, если она не находится в списке записей Win32Project1 c:\Users\Admin1\Documents\Visual Studio 2015\Projects\Win32Project1\Win32Project 1\Блок_.cpp 37
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
29.07.2015, 12:23
Цитата Сообщение от Ilot Посмотреть сообщение
Библиотека С++ (в разделе которого мы находимся ) кроссплатформена.
Цитата Сообщение от eagl69 Посмотреть сообщение
чтобы не грузить систему
библиотека да, а система нет
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
29.07.2015, 12:29
eagl69, в блямба-функции нужно хапать локальные переменные переменные:
C++
1
cv.wait(lk, [=]() { return (*strukt_1).a == 0;});
Либо делать переменные глобальными. Кажется так...
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
29.07.2015, 12:29  [ТС]
Цитата Сообщение от Praktolock Посмотреть сообщение
библиотека да, а система нет
Вы хотите сказать что циклом вполне можно обойтись? Но если убрать Sleep() то все виснет....
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
29.07.2015, 12:44
Цитата Сообщение от eagl69 Посмотреть сообщение
Вы хотите сказать что циклом вполне можно обойтись?
Конечно можно.
Цитата Сообщение от eagl69 Посмотреть сообщение
Но если убрать Sleep() то все виснет....
Как виснет? Наглухо или подтормаживает просто?
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
29.07.2015, 12:53  [ТС]
Цитата Сообщение от Praktolock Посмотреть сообщение
Как виснет? Наглухо или подтормаживает просто?
загрузка цп под 100% т.к. в цикл выполняется быстро. А зачем тогда придуманы эти condition_variable если и проверкой в цикле переменной вполне можно обойтись? Я так думал что пока поток не спит то он жрет ресурсы... поэтому его лучше приостановить.

Добавлено через 1 минуту
А можно послать уведомление одному из 10 потоков? а не всем сразу? например по его ID?

Добавлено через 13 секунд
А можно послать уведомление одному из 10 потоков? а не всем сразу? например по его ID?
0
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
29.07.2015, 13:01
Цитата Сообщение от eagl69 Посмотреть сообщение
загрузка цп под 100% т.к. в цикл выполняется быстро
Ну так не убирай Sleep)
Цитата Сообщение от eagl69 Посмотреть сообщение
А зачем тогда придуманы эти condition_variable если и проверкой в цикле переменной вполне можно обойтись?
С ними код компактнее и понятнее
Цитата Сообщение от eagl69 Посмотреть сообщение
А можно послать уведомление одному из 10 потоков? а не всем сразу? например по его ID?
Конечно можно. Ну самое что первое приходит в голову, вместо одной переменной сделать массив, в котором по одной такой переменной для каждого потока, и потоку например передавать указатель на егошнюю
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
29.07.2015, 13:02
Цитата Сообщение от eagl69 Посмотреть сообщение
А зачем тогда придуманы эти condition_variable если и проверкой в цикле переменной вполне можно обойтись?
Нельзя. Условные переменные это тот самый механизм, который позволяет ждать события не загружая систему.
Более того если пользоваться циклом переменная должна быть атомарна, либо необходимо заводить мъютекс для защиты флага.

Цитата Сообщение от eagl69 Посмотреть сообщение
А можно послать уведомление одному из 10 потоков? а не всем сразу? например по его ID?
Да. Функцией notify_one(). Разбудить все ожидающие потоки позволяет функция notify_all() условной переменной.
Что бы разбудить конкретный поток заведите для него отдельную условную переменную, ибо стандарт не дает никаких гарантий относительно того какой поток будет разбужен функцией notify_one().
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
29.07.2015, 13:09  [ТС]
У меня так и реализовано сейчас, но только проверка в цикле этих переменных. Вот я и подумал от них избавится.

Добавлено через 4 минуты
Я правильно понял что сделав массив перименных функцией notify_one() разбудится только тот поток где ожидается изменение именно той переменной? например так: cv.wait(lk, [=]() { return (*strukt_1)[1].a == 0;});

Добавлено через 55 секунд
а потоки где идет проверка:cv.wait(lk, [=]() { return (*strukt_1)[2].a == 0;}); не будут просыпаться?
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
29.07.2015, 13:13
eagl69, не правильно поняли. Нужно создавать массив условных переменных
C++
1
std::condition_variable cv[10];
И в каждом потоке ждать отдельную условную переменную.
C++
1
cv[index].wait(lk, [=]() { return /*условия могут отличаться для разных потоков*/;})
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
29.07.2015, 13:28  [ТС]
А можно сделать так: в структуре создать std::condition_variable cv; а массив сделать из структуры.
C++
1
2
3
4
5
6
7
struct a
{
int a=1;
std::condition_variable cv;
}
 
std::vector<a> aa(10);
Добавлено через 1 минуту
C++
1
aa[1].cv.wait(lk, [=]() { return /*условия могут отличаться для разных потоков*/;})
Добавлено через 1 минуту
Те хочу добиться чтобы каждой группе данных соответствовал свой condition_variable
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
29.07.2015, 13:34
Цитата Сообщение от eagl69 Посмотреть сообщение
Те хочу добиться чтобы каждой группе данных соответствовал свой condition_variable
Так будет правильнее и сия конструкция носит гордое название инкапсуляция.
Хотя вектор лучше не использовать.
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
29.07.2015, 13:43  [ТС]
А чем плох вектор?

Добавлено через 1 минуту
Дело в том что у меня в структуре данные разных типов....
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
29.07.2015, 13:54
Цитата Сообщение от eagl69 Посмотреть сообщение
А чем плох вектор?
Вектор требует наличие конструктора по умолчанию, конструктора копирования и оператора присвоения для хранимах объектов. Ни первого, ни второго, ни третьего у условных переменных нет. Вы элементарно не сможете поместить свои структуры в вектор с помощью push_back. Но если вы полагаете использовать emplace-функции то тоже можете нарваться на неприятности при перераспределении памяти вектора. Одним словом сплошные нихт зер гут.
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
29.07.2015, 14:02  [ТС]
А чем тогда лучше пользоваться?
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2224 / 1426 / 420
Регистрация: 16.05.2013
Сообщений: 3,646
Записей в блоге: 6
29.07.2015, 14:23
Цитата Сообщение от eagl69 Посмотреть сообщение
А чем тогда лучше пользоваться?
Массивы или независимое объявление.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.07.2015, 14:23
Помогаю со студенческими работами здесь

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

Взаимодействие между потоками
Привет. Есть класс А, который содержит не статические методы, которые можно вызвать лишь с главного потока. И есть класс Б, который...

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

Связь между потоками
Пытаюсь реализовать змейку на qt и вот остановился на моменте связи между основным и другим потоками. Кидаю код(благо он не очень...

Взаимодействие между потоками
Мне надо чтоб 1 поток перебирал числа из файла и , которые кратны 17, передавать второму потоку, который просто накапливает эти числа и...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru