Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
eagl69
4 / 9 / 1
Регистрация: 12.10.2011
Сообщений: 498
#1

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

29.07.2015, 11:35. Просмотров 614. Ответов 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.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.07.2015, 11:35     Уведомления между потоками
Посмотрите здесь:

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

Отправка уведомления на e-mail - C++
Здравствуйте. Искал на форуме данную тему.Точнее есть коды на PHP и C# но я не понимаю как с ними работать. Не нашел на С++.Как же все таки...

Добавить вывода уведомления если стек полон или пуст - C++
Приветствую Столкнулся маленькой проблемкой. В код необходимо дописать строчки, чтобы выводило "Стек полон" и "Стек пуст", при “overflow”...

Работа с потоками - C++
Добрый вечер. Возникла такая проблема: в консольном приложении воспроизводится музыка при помощи mciSendString(s.c_str(), NULL, 0,...

Работа с потоками - C++
Задача поставлена так : Необходимо открыть поток, записать некую информацию и далее закрыть его. Но необходимо, чтобы после закрытия...

Работа с потоками - C++
Нужно посчитать сумму элементов в матрице nxn написал а она мне выдаёт ошибку. и теперь не знаю что надо делать. ...

проблема с потоками - C++
Ребят при написании программы появилась проблема, опишу вкратце. пишу интерфейс WTL шаблонами. В MainWindow класса есть метод обработки...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
29.07.2015, 12:03     Уведомления между потоками #2
Используйте условные переменные. На вашем псевдокоде и по одному потоку для блока и сервиса код будет выглядеть вот так:
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;
}
Что бы более конкретно ответить на вопрос о синхронизации нужно знать больше о том как должны взаимодействовать между собой потоки.
Praktolock
65 / 65 / 1
Регистрация: 29.11.2011
Сообщений: 300
29.07.2015, 12:06     Уведомления между потоками #3
Ну это не по языку вопрос а по платформе, для которой этот код предназначен.
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
29.07.2015, 12:10     Уведомления между потоками #4
Цитата Сообщение от Praktolock Посмотреть сообщение
Ну это не по языку вопрос а по платформе, для которой этот код предназначен.
Библиотека С++ (в разделе которого мы находимся ) кроссплатформена.
eagl69
4 / 9 / 1
Регистрация: 12.10.2011
Сообщений: 498
29.07.2015, 12:23  [ТС]     Уведомления между потоками #5
C++
1
cv.wait(lk, []() { return (*strukt_1).a == 0;});
здесь выдает 2 ошибки:

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

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

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

Добавлено через 13 секунд
А можно послать уведомление одному из 10 потоков? а не всем сразу? например по его ID?
Praktolock
65 / 65 / 1
Регистрация: 29.11.2011
Сообщений: 300
29.07.2015, 13:01     Уведомления между потоками #11
Цитата Сообщение от eagl69 Посмотреть сообщение
загрузка цп под 100% т.к. в цикл выполняется быстро
Ну так не убирай Sleep)
Цитата Сообщение от eagl69 Посмотреть сообщение
А зачем тогда придуманы эти condition_variable если и проверкой в цикле переменной вполне можно обойтись?
С ними код компактнее и понятнее
Цитата Сообщение от eagl69 Посмотреть сообщение
А можно послать уведомление одному из 10 потоков? а не всем сразу? например по его ID?
Конечно можно. Ну самое что первое приходит в голову, вместо одной переменной сделать массив, в котором по одной такой переменной для каждого потока, и потоку например передавать указатель на егошнюю
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
29.07.2015, 13:02     Уведомления между потоками #12
Цитата Сообщение от eagl69 Посмотреть сообщение
А зачем тогда придуманы эти condition_variable если и проверкой в цикле переменной вполне можно обойтись?
Нельзя. Условные переменные это тот самый механизм, который позволяет ждать события не загружая систему.
Более того если пользоваться циклом переменная должна быть атомарна, либо необходимо заводить мъютекс для защиты флага.

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

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

Добавлено через 55 секунд
а потоки где идет проверка:cv.wait(lk, [=]() { return (*strukt_1)[2].a == 0;}); не будут просыпаться?
Ilot
Модератор
Эксперт С++
1807 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 5
Завершенные тесты: 1
29.07.2015, 13:13     Уведомления между потоками #14
eagl69, не правильно поняли. Нужно создавать массив условных переменных
C++
1
std::condition_variable cv[10];
И в каждом потоке ждать отдельную условную переменную.
C++
1
cv[index].wait(lk, [=]() { return /*условия могут отличаться для разных потоков*/;})
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.07.2015, 13:28     Уведомления между потоками
Еще ссылки по теме:

Работа с потоками - C++
Пишу простой RSS агрегатор и уже практически доделал его в программе параллельно устанавливается соединение и потом извлекаем данные из...

Работа с потоками - C++
Поток main должен выполнить следующие действия: создать массив, размерность и элементы которого вводятся пользователем с консоли; ...

работа с потоками - C++
Добрый вечер! Есть файл txt, состоит из символов, чисел, необходимо его открыть, упорядочить некоторым образом и записать, начал с...

Парсинг потоками - C++
Здравствуйте. У меня есть текстовый файл объёмом где-то 10-50 мегобайт. В нём в текстовом виде хранятся числа и строки в известном мне...

Работа с потоками - C++
Задание Разработать программу, реализующую многопочность средствами среды Win32. Программа должна обеспечивать: Отображение списка...


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

Или воспользуйтесь поиском по форуму:
eagl69
4 / 9 / 1
Регистрация: 12.10.2011
Сообщений: 498
29.07.2015, 13:28  [ТС]     Уведомления между потоками #15
А можно сделать так: в структуре создать 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
Yandex
Объявления
29.07.2015, 13:28     Уведомления между потоками
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru