Безопасно ли передавать аргументы посредством ссылки в функцию std:: thread?

#include <thread>
#include <string>
#include <vector>
#include <chrono>

using namespace std;

void f(const vector<string>& coll)
{
    this_thread::sleep_for(1h);

    //
    // Is coll guaranteed to be valid before exiting this function?
    //
}

int main()
{
    {
        vector<string> coll(1024 * 1024 * 100);
        thread(f, coll).detach();
    }

    //
    // I know std::thread will copy arguments into itself by default, 
    // but I don't know whether these copied objects are still valid
    // after the std::thread object has been destroyed.
    //

    while (true);
}

Безопасно ли передавать аргументы посредством ссылки в функцию std:: thread?

Ответы

Ответ 1

  • Является ли coll гарантированным быть действительным до выхода из этой функции?

    • Обновлено: Да. Когда вы передаете coll конструктору потока в функции main, потому что coll - это объект, он скопирован decay. Этот decay копирует по существу move вектор (поэтому он становится rvalue), который будет привязан к параметру coll в f во время выполнения потока. (Спасибо за комментарий @Praetorian)
  • Безопасно ли передавать аргументы по ссылке в функцию std:: thread?

    • Ваши аргументы decay скопированы, поэтому вы фактически никогда не пропускаете ничего по ссылке std::thread.
  • Ссылка для std::decay: http://www.cplusplus.com/reference/type_traits/decay/

  • Принятый ответ в этом вопросе std:: thread с подвижным, не скопируемым аргументом объяснил, что происходит с аргументами, переданными в std::thread

Ответ 2

Как @T.C. комментарий, вы не передаете ссылку на поток, вы просто делаете копию вектора в потоке:

thread(f, coll).detach(); // It NOT pass by reference, but makes a copy.

Если вы действительно хотите пройти по ссылке, вы должны написать это:

thread(f, std::ref(coll)).detach(); // Use std::ref to pass by reference

Затем код получит ошибку сегмента, если поток пытается получить доступ к вектору, так как при запуске потока он очень вероятно, что вектор разрушен.

Итак, на ваш вопрос:

Безопасно ли передавать аргументы посредством ссылки в функцию std:: thread?

  • Безопасно, если вы уверены, что объект остается действительным во время выполнения потока.
  • Небезопасно, если объект разрушен, и вы получите ошибку сегмента.