Я пишу многопоточную программу на C++, используя библиотеку потоков C++ 11.Управление несколькими параллельными потоками
У меня есть следующие требования:
- Основной поток прослушивает к некоторому типу событий, и выстреливает новый поток для каждого нового события
- Когда завершение программы запрашиваются, новое творение потока блокируется и мы ждем завершения старых потоков
У меня есть возможность хранить потоки в некотором контейнере, например, список. Перед выходом все нити в контейнере: join()
-ed. Однако, поскольку контейнеры STL не являются потокобезопасными, необходима дополнительная синхронизация при добавлении нового потока и удалении готового потока из контейнера. В этом случае взаимодействие между основным потоком и дочерними потоками становится немного сложнее. Должна ли дочерняя нить удаляться из контейнера? Если нет, то как он может сообщить основному потоку, когда пришло время удалить? и т. д.
Еще один способ, по которому я вижу, состоит в том, чтобы иметь атомный int, который увеличивается при помощи основного потока при создании дочернего потока и декрементируется дочерним потоком прямо перед его завершением (потоки будут detach()
-ed после создания, поэтому мне не придется управлять любыми объектами std :: thread). Перед выходом, мы просто ожидаем, что атомное целое число станет 0 в простой петле. Это решение выглядит лучше для меня, потому что есть меньше движущихся частей и нет блокировки (по крайней мере, до тех пор, пока целевая платформа имеет незафиксированную реализацию std::atomic<int>
).
Итак, мой вопрос в том, какой из вышеперечисленных методов вы предпочитаете?
Вам нужна новая тема для каждого мероприятия? Если у вас много, и особенно если они короткие, создание/уничтожение потоков будет огромным накладным. В зависимости от вашей ситуации вы можете реализовать какой-то пул потоков с фиксированным количеством рабочих потоков. Просто предложение –
Если основной поток уже прослушивает события, почему дочерние потоки не могут отправлять основной поток, сигнализируя о завершении события? Тогда только основной поток когда-либо коснется контейнера, и синхронизация не требуется. – ildjarn
@ АлександрКондрацкий Я знаю, но это был осознанный выбор. У меня мало что происходит, и дочерние потоки могут занять значительное время, поэтому я не вижу необходимости использовать пул потоков. –