Да, вы несете ответственность за управление временем жизни semaphore
и должны проявлять особую осторожность, когда поток, создающий semaphore
, может быть пережит другим потоком, используя semaphore
.
Наивный подход должен был бы передать semaphore
по ссылке. Хотя это сработало бы, если бы вы могли гарантировать, что ссылка остается действительной в течение срока службы потока B, в описанной ситуации этого не произойдет.
/* Thread B function signature: void ThreadB(std::shared_ptr<std::binary_semaphore>& done); */
auto done {std::make_shared<std::binary_semphore>(0)};
SubmitToMessageThread([&done]() { ThreadB(done); }));
if (done.wait_for(std::chrono::seconds(1)))
/* work with resource if thread B has called done->release() to indicate the resource is ready*/
else
/* make do without the resource */
Но поток B не имеет такой гарантии срока службы. * Поток A wait_for
может истечь до завершения потока B, а поток A может go завершиться, что приведет к разрушению semaphore
перед использованием потоком B. Мы должны управлять временем жизни, обычно с shared_ptr
. Например, следующее:
/* Thread B function signature: void ThreadB(std::shared_ptr<std::binary_semaphore> done); */
auto done {std::make_shared<std::binary_semphore>(0)};
SubmitToMessageThread([done]() { ThreadB(done); }));
if (done.wait_for(std::chrono::seconds(1)))
/* work with resource if thread B has called done->release() to indicate the resource is ready*/
else
/* make do without the resource */
Таким образом, семафоры предоставляют еще одну возможность использования огнестрельного оружия, если с жизненным циклом не управлять тщательно.