Безопасно ли передавать аргументы посредством ссылки в функцию 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?
- Безопасно, если вы уверены, что объект остается действительным во время выполнения потока.
- Небезопасно, если объект разрушен, и вы получите ошибку сегмента.