Думайте об объединяющем `thread` как о контейнере с областью действия
Причина
Чтобы сохранить безопасность указателя и избежать утечек, нам нужно рассмотреть, какие указатели используются thread. Если thread объединяется, мы можем безопасно передавать указатели на объекты в области действия thread и его охватывающих областей.
Пример
void f(int* p)
{
// ...
*p = 99;
// ...
}
int glob = 33;
void some_fct(int* p)
{
int x = 77;
joining_thread t0(f, &x); // ОК
joining_thread t1(f, p); // ОК
joining_thread t2(f, &glob); // ОК
auto q = make_unique<int>(99);
joining_thread t3(f, q.get()); // ОК
// ...
}
gsl::joining_thread — это std::thread с деструктором, который объединяется и который не может быть detached(). По "ОК" мы имеем в виду, что объект будет в области действия ("живо") столько времени, сколько thread может использовать указатель на него. Тот факт, что threads работают одновременно, не влияет на проблемы жизненного цикла или владения здесь; эти threads можно рассматривать как просто объект функции, вызываемый из some_fct.
Применение
Убедитесь, что joining_threads не detach(). После этого обычное применение жизненного цикла и владения (для локальных объектов) применяется.