|
97 / 0 / 1
Регистрация: 01.07.2018
Сообщений: 25
|
|
Синхронизация потоков с time_point28.05.2020, 12:08. Показов 3900. Ответов 41
Метки нет (Все метки)
В программе запускается два потока, первым-поток, ожидающий инструкций от пользователя( выводит строку, ожидает ввод, запускает соответствующую функцию-либо изменяет общий контейнер, либо выводит из него данные), вторым запускается поток, выводящий точно по time_point данные из общего контейнера. Как синхронизировать потоки? Приложение пока консольное, проблема в том, что второй поток должен всегда точно по времени выводить сообщения и если первый считает информацию слишком поздно( не успеет выполнить вывод до очередной временной точки), то вывод со второго потока не успеет сработать вовремя. Думаю использовать timed_mutex, блокировать второй поток точно по времени, а в первом использовать try_lock_until( time_point-chrono::milliseconds(500). Есть ли более оптимальный вариант?
0
|
|
| 28.05.2020, 12:08 | |
|
Ответы с готовыми решениями:
41
Как привести тип time_point<std::filesystem::__file_clock, [.]>к типу const time_point<std::chrono::_V2::system_clock Синхронизация потоков
|
|
Комп_Оратор)
|
|||
| 02.06.2020, 18:47 | |||
|
Вообще интересный разговор. Буду думать. ![]() Добавлено через 2 минуты
0
|
|||
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
|||||||
| 02.06.2020, 18:49 | |||||||
Блокировка здесь ни при чём
0
|
|||||||
|
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
|
|||
| 02.06.2020, 18:51 | |||
|
1
|
|||
|
Комп_Оратор)
|
||
| 02.06.2020, 18:52 | ||
|
0
|
||
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
|
| 02.06.2020, 18:53 | |
|
0
|
|
|
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
|
||
| 02.06.2020, 18:55 | ||
|
0
|
||
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
||
| 02.06.2020, 18:57 | ||
|
1
|
||
|
Комп_Оратор)
|
|||||||||||||
| 02.06.2020, 18:58 | |||||||||||||
continue_work именно печатающий. Он перекроет кислород заталкивающему перед нотификацией. Он подмутексом пишет переменную
0
|
|||||||||||||
|
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
|
|||||
| 02.06.2020, 19:08 | |||||
Добавлено через 6 минут
0
|
|||||
|
Комп_Оратор)
|
||||
| 02.06.2020, 19:14 | ||||
|
Ответьте на простой вопрос: изменение значения continue_work когда-нибудь отловится в потоке задачи печати (больше ни кто эту переменную не контролирует) ?Добавлено через 1 минуту Добавлено через 2 минуты
0
|
||||
|
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
|
|||||||
| 02.06.2020, 19:18 | |||||||
|
Но у вас запись и чтение не атомарной переменной не синхронизированны! Я поясню так:
0
|
|||||||
|
Комп_Оратор)
|
||
| 02.06.2020, 19:27 | ||
|
Думаю, не стоит это продолжать, я почитаю ещё, конечно и найдя приличные примеры у того же Уильямса - покажу. Продолжение ни чего не даст, так как доказательств нет ни у одной из сторон.
0
|
||
|
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
|
||||
| 02.06.2020, 19:34 | ||||
![]() Добавлено через 1 минуту
0
|
||||
|
Комп_Оратор)
|
|||
| 02.06.2020, 20:09 | |||
![]() Добавлено через 46 секунд ![]() Добавлено через 14 минут там можно было бы задать данную переменную с клавиатуры, а не присваивать после ввода любого символа. Но с учётом замечания oleg-m1973, про volalile это не нужно)
0
|
|||
|
6353 / 3524 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
|
|||
| 02.06.2020, 20:18 | |||
|
Добавлено через 7 минут
0
|
|||
|
Комп_Оратор)
|
||
| 02.06.2020, 20:31 | ||
|
0
|
||
|
97 / 0 / 1
Регистрация: 01.07.2018
Сообщений: 25
|
|
| 03.06.2020, 09:26 [ТС] | |
|
Я не могу использовать CV.wait() потому, что в функции, через которую юзер общается с программой, порядка 10 различных вопросов, которые программа ему задает. С CV.wait() проходит только 1 вопрос на 1 вывод таймпоинта первым потоком. Программа должна выводить вопросы юзеру до тех пор, пока до очередного таймпоинта не останется 5 секунд(чтобы успеть выполнить последний запрос), и если ввод данных попадает в эти последние 5 сек, то поток юзера засыпает до таймпоинт + 1 секунда(чтобы точно не помешать вовремя вывести напоминание).Пока самым оптимальным видится такой вариант, но постоянно на всех функциях, при попадании в эти 5 секунд, выдает такую ошибку "Вызвано исключение: нарушение доступа для чтения.
_Right_scary было nullptr." Причем, если не попадать в этот промежуток, все функции работают. void f(set<pair<chrono::system_clock::time_poi nt, int64_t> >& TP, map<Store*, vector<shared_ptr<Store::Child > > >&Children) { set<pair<chrono::system_clock::time_poin t, int64_t> > ::iterator it; for (it = TP.begin(); it != TP.end(); it++) { Tp_Next = it->first+chrono::seconds(1); Tp_Try = it->first - chrono::seconds(5); time_t ON= std::chrono::system_clock::to_time_t(it->first); tm on; localtime_s(&on, &ON); int year1 = on.tm_year+1900, month=on.tm_mon+1, day=on.tm_mday; string S = ""; ostringstream sstr; sstr << year1<<month<<day; S=sstr.str(); map<Store*, vector<shared_ptr<Store::Child > > >::iterator it1; this_thread::sleep_until(it->first); unique_lock<mutex>UL1(MU); cout << endl << "TIME :" << endl; for (it1 = Children.begin(); it1 != Children.end(); it1++) { if (it1->first->Name == S) { it1->first->Get(it1->first->mp, it->second); } break; } } } void User_Request(map< Store*, vector<shared_ptr<Store::Child > > >& Children) { string Answer1, Answer, Object, Main_Object = ""; bool Bl = true; while ((chrono::system_clock::now()) <= Tp_End) { if ((chrono::system_clock::now()) > Tp_Try) { this_thread::sleep_until(Tp_Next ); } {unique_lock<mutex>UL1(MU); cout << "Do you need to work with the main objects' store or with its' substore?"; } cin >> Answer1; if ((chrono::system_clock::now()) > Tp_Try) { this_thread::sleep_until(Tp_Next ); } {unique_lock<mutex>UL1(MU); cout << "Enter the name"; } cin >> Object; if ((chrono::system_clock::now()) > Tp_Try) { this_thread::sleep_until(Tp_Next); } {unique_lock<mutex>UL1(MU); cout << "What do you need to do ? Enter get, update, show, query, range_query, remove"; } cin >> Answer; (Answer1.find("main") != -1) ? Bl = true : Bl = !Bl; shared_ptr<Store >Obj; shared_ptr<Store::Child> Obj1; Store* x = nullptr; ; map<Store*, vector<shared_ptr<Store::Child > > >::iterator it; if (Bl == true) { for (it = Children.begin(); it != Children.end(); it++) { if (it->first->Name == Object) { Obj.reset(x); break; } } } else { for (it = Children.begin(); it != Children.end(); it++) { for (auto it2 : it->second) { if (it2->Name == Object) { Obj1 = it2; break; } } } } string key, value; double a, b; int64_t ID = 0; if (Answer == "get") { if ((chrono::system_clock::now()) > Tp_Try) { this_thread::sleep_until(Tp_Next ); } {unique_lock<mutex>UL1(MU); cout << "Enter the ID"; } cin >> ID; if ((chrono::system_clock::now()) > Tp_Try) { this_thread::sleep_until(Tp_Next ); } {unique_lock<mutex>UL1(MU); (Bl == true) ? Obj->Get(Obj->mp, ID) : Obj1->Get(ID); } } else if (Answer == "update") { if ((chrono::system_clock::now()) > Tp_Try) { this_thread::sleep_until(Tp_Next ); } {unique_lock<mutex>UL1(MU); cout << "Enter the ID, key, value"; } cin >> ID >> key >> value; if ((chrono::system_clock::now()) > Tp_Try) { this_thread::sleep_until(Tp_Next); } {unique_lock<mutex>UL1(MU); (Bl == true) ? Obj->Update(ID, key, value) : Obj1->Update(ID, key, value); } } else if (Answer == "show") { if ((chrono::system_clock::now()) > Tp_Try) { this_thread::sleep_until(Tp_Next); } {unique_lock<mutex>UL1(MU); (Bl == true) ? Obj->Show(Obj->mp) : Obj1->Show(); } } } } Как это исправить? Добавлено через 1 час 54 минуты Может, кто знает, как вообще можно так потоки синхронизировать, чтобы напоминания по таймпонту всегда точно вовремя выводились, но и второй поток на юзера продолжал работать до последнего таймпоинта?
0
|
|
|
Комп_Оратор)
|
|||||||
| 03.06.2020, 10:26 | |||||||
|
А теперь смотрите на верхнюю линейку окна редактора, где набираете текст. Вторая позиция в среднем (2-м с верху/низу) ряду выглядит как С++. Кликнув мышкой вы увидите пару тегов в текущей позиции: [CPP][/CPP] Если там написать std::cout<<"Hello"; Получим: [CPP]std::cout<<"Hello";[/CPP] и в готовом отображаемом читателям тексте оно будет выглядеть как:
Что касается указателя на предикат, передаваемого условной переменной, то работу в нём делать вообще не желательно (мягко говоря). Это простая встраиваемая (как правило) функция которая возвращает bool. Это обычно лямбда даже. Вы можете целый день таскать контейнеры, укладывать их штабелями, сгребать и разгребать, а в момент когда результат достигнут (и украшен прекрасными цветами) вы устанавливаете переменную bool (можно и сайдэффектом обойтись, но я пока советую вручную) которую вернёт ваш предикат. А потом вызываете wait. Почитайте о том как это работает. Я уже кое где упомянул даже в этом топике.
1
|
|||||||
|
97 / 0 / 1
Регистрация: 01.07.2018
Сообщений: 25
|
||||||
| 03.06.2020, 11:11 [ТС] | ||||||
|
Спасибо за подсказку с тегами. Где именно в этой программе вызывать wait?
0
|
||||||
|
Комп_Оратор)
|
||||
| 03.06.2020, 12:06 | ||||
![]() цикле ожидания) чтобы понять - просыпаться и хватать мутекс и делать вашу таску или спать дальше и ждать.Для этого посмотрите мой код. Или можете воспользоваться решением oleg-m1973, для моей задачи. Там легче принимать решение из корневого потока ( main()).Главное, это то что код задачи не размещён в предикате. Он в защищаемой секции размещён. А мьютекс включает-выключает условная переменная. Это даёт возможность разгрузить партнёрский поток от нескончаемого вопроса: "ну ты закончил или нет?!". Переменная разлочит свою часть и уводит спать свой поток. Партнёр сам уведомляет о финише, - будит. А cv при пробуждении проверяет условие и возвращает управление своему потоку захватив мутекс. Теперь партнёр ждёт. Он может быть под простым мутексом, кстати. Я сделал симметрично, но это не обязательно. ![]() Добавлено через 7 минут Dgamilya, если вам только время нужно, то наверное то, что я показал, - лишнее.
0
|
||||
| 03.06.2020, 12:06 | |
|
Синхронизация потоков в c++
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет:
1. Использовать системное время и дату,
2. Есть возможность вводить время и дату вручную.
3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
|
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber.
Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
|
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео:
https:/ / vkvideo. ru/ video-240781534_456239017
YouTube:
eY5-5PyI9NM
Текстовая версия
|
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать
Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
|
|
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства.
Родственных связей существует 8 ступеней, такие как:
p - отец
P - мать
q - муж
Q - жена
b - брат
B - сестра
s - сын
S - дочь
|
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире.
Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
|
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С.
Задача:
Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
|
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
|