|
Заблокирован
|
||||||
Std::thread приостановка потока05.08.2015, 21:47. Показов 12863. Ответов 25
Метки нет (Все метки)
Есть прога в C++ Builder. Три функции описаные внизу запускаются в трех разных потоках. Первый поток генерирует данные для для двух других, запускает их и сам приостанавливается. Каждый из двух других потоков после выполнения увеличивает переменную flag и приостанавливается, и тот поток который отработал последним проверяет и если flag==2, то запускает первый поток(тот который генерирует данные), а сам останавливается.
То есть работает первый поток, потом два других в паралели, потом опять первый, потом опять два других в паралели... Кликните здесь для просмотра всего текста
интересует как в std::thread реализовать подобие работы методов ->Suspend() и ->Resume() если кому интересно вся программа лежит тут
0
|
||||||
| 05.08.2015, 21:47 | |
|
Ответы с готовыми решениями:
25
Использование std::function в std::thread |
|
|
|||||||
| 06.08.2015, 11:58 | |||||||
0
|
|||||||
|
Заблокирован
|
|
| 06.08.2015, 15:14 [ТС] | |
|
тут я привел сильно упрощенный вариант, чтобы было понятно как все должно работать.
1. основной поток(Execute): читает данные из массива, текуший элемент (it) передается в потоки, после этого он (основной поток) размораживает поток 1 и поток 2, а сам останавливается. 2. поток 1(Generation): в зависимости от значения it генерирует данные и добавляет их в конец списка (listData), после того как все данные добавлены поток останавливается 3. поток 2(Delete): в зависимости от значения (it) удаляет элементы из списка(listData), причем не трогает элементы которые возможно уже добавил поток 1 на текущей итерации, после того как все данные по условию удалены поток останавливается для того чтобы вновь разморозить основной поток, когда все паралельные потоки завершили работу и был введен флаг, то есть последний из параллельных потоков по этому флагу смотрит, что он именно он последний завершает текущую итерацию, и запускает основной поток, который прочитает новый элемент из входного массива, относительно которого и будет запущена новая итерация обработки в потоке 1 и потоке 2. Как это можно было сделать в Builder хитрее я незнаю. Потоки создаются в самом начале, а удаляются в самом конце, т.к. тратить время и ресурсы на постоянное их создание не есть хорошо, учитывая что входной массив это больше 10 млн элементов.
0
|
|
|
|
||||||||
| 06.08.2015, 15:54 | ||||||||
|
Приведенный выше код полностью подходит под ваше описание.
Начнем с конца.
Уведомлять поток 1 о завершении работы потока 2 можно с помощью условных переменных.
1
|
||||||||
|
Заблокирован
|
||
| 06.08.2015, 16:17 [ТС] | ||
|
А за идею добавления данных блоком спасибо)
0
|
||
|
|
||
| 06.08.2015, 16:19 | ||
|
Обычно виндой используют объекты-события (CreateEvent() + WaitForSingleObject() и кстати тут тоже нужно быть внимательным дедлокам) или системную очередь сообщений. Если пользоваться стандартными средствами С++, то вероятно стоит смотреть в std::mutex+std::condition_variable
0
|
||
|
|
||
| 06.08.2015, 16:52 | ||
|
Ну так вот. Вместо потоков используйте упакованные задачи, а сами потоки организуйте как пул. Подробнее можно почитать у Энтони Уильямса Параллельное программирование в действии.
0
|
||
|
Заблокирован
|
|
| 07.08.2015, 23:59 [ТС] | |
|
я правильно понимаю что для каждого из параллельных потоков нужна своя условная переменная, т.к. если использовать одну, то один из потоков после выполнения .notify_all() в основном потоке, заблокирует mutex и выйдет из .wait, а второй будет ждать когда он его освободит и никакой параллельности не будет?
0
|
|
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|||||||||||||||||||||||||||||||||||||
| 08.08.2015, 12:11 | |||||||||||||||||||||||||||||||||||||
|
профессиональный кросс-платформенный инструмент. если же ваша цель - научиться самому строить подобные механизмы, тогда предлагаю вашему вниманию рассмотреть конструкцию учебного тред-пула. она очень простая, и должно быть, содержит ответы на все ваши вопросы. итак: файлы проекта:
содержит пример-иллюстрацию использования atomic_stream.h атомарный вывод данных в консоль напоминает std::cout, но вывод не коверкается, когда несколько потоков одновременно пишут в консоль только для отладочных целей. task_queue очередь задач. по сути, это просто thread-safe очередь из std::function thread_pool учебная модель тред-пула ----------------------------------------------------------------------------- main.cpp
atomic_stream.h
task_queue.h
thread_pool.h
----------------------------------------------------------------------------------- тестировался на компиляторах: cl(visual studio 2012/2013), mingw482, gcc(версию запамятовал). если что нибудь не понятно, или будут какие то ошибки - спрашивайте.
8
|
|||||||||||||||||||||||||||||||||||||
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
||
| 08.08.2015, 12:48 | ||
|
Можно еще typedef заменить на using, а объявления в private-секции без определений на =delete.
1
|
||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|||
| 08.08.2015, 16:14 | |||
|
и эта правка была сделанна уже в более поздний период. вообще, это не принципиально. можно вообще убрать универсальные ссылки, заменив их константными ссылками. смысл от этого не изменится. поэтому, и заморачиваться особо здесь смысла не имеет. он бы тогда на msvc2012 не взлетел.
0
|
|||
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
|||
| 08.08.2015, 16:52 | |||
|
0
|
|||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|||||||||
| 08.08.2015, 17:05 | |||||||||
|
я перефразирую: что именно в коде лично вам не понятно? читабельность ради читабельности не нужна. если вы понимаете смысл подобной записи:
делать его ещё читабельнее - можно, если есть время, и нет причин этому припятствующих. по которой я и не стал наводить такую косметику. недостаточная поддержка с++11. то есть, вы конечно можете ещё улучшить читабельность, потратив время на рефактор того, что и так работает. и при этом собирается на старых компиляторах. лично я не вижу в этом никакого смысла.
0
|
|||||||||
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
|||||||||
| 08.08.2015, 22:42 | |||||||||
Давай отвлечемся от компиляторов. Вообще главный смысл =delete (для функций-членов) вот в чем. Их даже два.1) При обращении из функций-членов класса и дружественных функций мы получаем ошибку компиляции, а не компоновки. Это как минимум меньше раздражает ![]() 2) Мне достаточно просмотреть public-секцию для того, чтобы иметь полное представление об интерфейсе класса. При использовании же костыля С++03 (согласись, это все-таки совсем не интуитивно для тех, кто видит такое в первый раз) мне нужно еще взглянуть и на private-секцию.
2
|
|||||||||
|
Заблокирован
|
|||||||
| 09.08.2015, 14:13 [ТС] | |||||||
|
я слабо представляю как можно применить пул потоков к моей задаче, вот временная диаграмма чтоб было понятнее в какое время какие потоки должны работать (см.вложение).
вот что у меня получилось пока, временами программа работает хорошо, но иногда зависает и не могу понять почему. может кто подскажет.
0
|
|||||||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 09.08.2015, 14:57 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
поскольку нарушает правило Роббинсона: "то, чего быть не должно - не должно произойти в принципе" разработчику класса не интересны ваши домыслы. внутри он сделает как захочет. все, о чем вы можете думать, глядя на интерфейс - это как работать с самим интерфейсом. при этом вы не должны делать предположения о деталях реализации. но он не вправе на это закладываться. потому что он не знает, что там под капотом. и это не его ума дело. вам нужно четко определиться, с какой позиции вы рассуждаете: с позиции пользователя? или с позиции разработчика? потому что если с позиции пользователя, то у него нет на руках никаких "фактов". потому что это не уго ума дело, что там под капотом. а если с позиции разработчика - есть интерфейс. и в рамках этого интерфейса вы можете менять реализацию, как захотите. можете повтыкать std::forward, если угодно. и казалось бы - манипулировать фактами, как захотите. но давайте глянем на код добавления задачи:
итого: разницы никакой. я согласен, что использование std::forward - привентивно увеличивает эффективность кода. однако, закладываться на то, что код действительно будет эффективнее нельзя. поэтому, заблуждение здесь - именно полагать, что раз мув, значит обязательно эффективнее. сейчас не буду вдаваться в подробности:
в реальности, это отдельный класс, который уже в разных местах используется. и там эта функция-член востребованна. обуславливается нежеланием раз за разом "легко реализовывать то, что можно было бы не реализовывать, а сразу же использовать". потому что во многих местах требуется именно этот функционал. можно было бы оформить в виде свободной функции. однако есть причины так не делать: 1. нарушает дизайн. либо так:
связанно с неймспейсами. и кстати, на свой практике я неоднократно с подобным встречался. существует требование к проекту, согласно которому, собственность проекта должна жить в нейспейсе проекта. когда разрабатывался класс TaskQueue, как раз таки было такое требование. допустим, пусть такой неймспейс называется sample. тогда:
можно использовать:
Резюмируя: поэтому, лично я допускаю в апи класса некий наиболее востребованный функциал, предпочитая это свободным функциям. +1. но это все - косметика. и это не причина запарывать с++03. а что касается новичков - ну все бывает в первый раз. некоторые практикуют наседование от nocopyable. но лично я предпочитаю минимизировать кол-во классов, если такой аскетизм не причиняет мне боль и страдания. Добавлено через 8 минут которая создает другие задачи. вот она создала 3 таких задачи. и подкрутила атомарный счетчик на 3. и заснула. эти 3 задачи начали исполняться в пуле потоков. когда задача завершается, она уменьшает счетчик. и проверяет: если счетчик дошел до 0, то такая последняя задача пробуждает задачу "менеджер". и отваливается. задача "менеджер" просыпается, и все повторяется. и так до тех пор, пока первая задача не просигналит об остановке пула.
0
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
|||||||
| 09.08.2015, 16:47 | |||||||
![]() 2) Это отчасти и его ума дело. Вот ты берешь ассоциативный контейнер. Тебе _нужно_ знать, как он устроен. Красно-черные деревья это или хэш-таблица. Если хэш-таблица, то separate chaining или open addressing. Если open addresing, то какой именно. Насколько дружелюбна к кэш-памяти. Это вроде как детали реализации, но они должны быть _статичны_, _почти не меняться со временем_, описаны в документации, потому что от них зависит принятие решения о выборе библиотеки. Так и тут - если ты используешь в интерфейсе универсальные ссылки и прочую мощь С++11, то будь добр, укажи явно, что семантика перемещений в пролете. Тогда я возьму другую библиотеку, потому что у меня в проекте дофига классов с тяжелым копированием и легким перемещением. Еще пример: если ты используешь либу для вывода логов асинхронно, ты вправе знать и закладываться на то, используется там блокировка или лок-фри. Потому как это сильно влияет на производительность и выбор либы, если у тебя прямо в лог так и прет. Хотя, казалось бы, - деталь реализации. Добавлено через 12 минут void push (const value_type& val); void push (value_type&& val);
0
|
|||||||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|||||||
| 09.08.2015, 16:55 | |||||||
|
ещё раз: детали реализации - его личное дело. выше я привел пример, где форвард конструкция не имеет профита. даже более того - очень многие ребята понятия не имеют ни о каких "красно-черных деревьях", и как std::map устроен внутри. но это никак не мешает им пользоваться. если для того, что бы просто пользоваться механизмом, необходимо знать подробности устройства - это говнокод. официально, std::unordered_map - это неупорядочный ассоциативный массив. это все, что вам гарантируется. под капотом там может быть все что угодно. сегодня может быть одно, а завтра - другое. но как то гемморно каждую фряшку так обрабатывать. удобно тайпдефнуть класс целиком один раз.
0
|
|||||||
| 09.08.2015, 16:55 | |
|
Помогаю со студенческими работами здесь
20
Ошибка компиляции "no instance of constructor 'std::thread::thread' matches the argument list" Boost::thread vs std::thread
Приостановка выполнения процесса/потока (windows) std::thread Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
|
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
|
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога
Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
|
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование
. \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json>
Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом.
# Check if. . .
|
|
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так:
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347
Основана на STM32F303RBT6.
На борту пять. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|