将 std::shared_ptr 传递给函数对象 std::thread
Passing a std::shared_ptr to a function object to std::thread
需要让这个 Functor 和我的线程一样长,所以我为它创建了一个 shared_ptr 并试图将它传递给 std::thread。我已经在此处复制了代码和错误列表。
struct Functor
{
std::string greeting;
explicit Functor(std::string _greeting="Hello!"): greeting { _greeting } {}
void operator()()
{
std::cout << greeting << "\n";
}
};
auto main() ->int
{
std::shared_ptr<Functor> fp = std::make_shared<Functor> ();
std::thread t(&fp);
t.join();
return 0;
}
错误列表:
Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)' std_threads C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\thr\xthread 240
Error C2672 'std::invoke': no matching overloaded function found std_threads C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\thr\xthread 240
我是 c++11 和并发的新手。请帮助我理解以下内容
1>当按值传递时,std::thread 是否总是在对象内部调用 operator()?如果是,为什么这么定义。
2>如何确保提供给线程的资源与线程一样长?
3>这里写的Functor是函数对象吗?
4>我在这段代码中做了什么?!
1>does a std::thread always invoke the operator() inside an object
when passed by value ? If so, why it has been defined so.
std::thread
调用 std::invoke
。来自 cppreference,如果第一个参数既不是 pointer to member function
也不是 pointer to data member
;它被视为一个函数对象。
因此,将调用 fp()。
INVOKE(f, t1, t2, ..., tN) is equivalent to f(t1, t2, ..., tN) (that
is, f is a FunctionObject)
所以你基本上可以做到std::thread t{*fp}
2>how to ensure that a resource given to a thread stays around as long
as the thread does?
您可以 shared_ptr
提供共享对象的所有权。或者您可以通过确保传递的资源在范围内来手动执行此操作。里程不同。
3>is the Functor written here, a function object ?
是的。 FunctionObject 类型是可以在函数调用运算符左侧使用的对象类型。但是 fp
不是。但是 *fp
是。
4>What have I done here in this code ?!
您可以通过显式传递带有参数 fp.get()
的 Functor::operator()
来使其工作。当然,一个简单的方法就是传递 *fp
std::shared_ptr<Functor>
不可调用 - 它不实现 operator()
,即使 Functor
实现。
这里shared_ptr
的目的是什么?为什么不干脆
int main() {
Functor f;
std::thread t(std::ref(f));
t.join();
return 0;
}
如果出于某种原因您坚持让 Functor
实例由 shared_ptr
管理,这是一种方法:
int main() {
std::shared_ptr<Functor> fp = std::make_shared<Functor> ();
std::thread t([fp]() { (*fp)(); });
t.join();
return 0;
}
您仍然可以使用以下语法让 std::thread
取得您的智能指针的所有权:
std::shared_ptr<Functor> f = std::make_shared<Functor>();
std::thread thread (&Functor::operator(), f);
thread.detach();
如果第一个参数是成员函数指针,那么第二个参数应该是对 class 实例的引用或指针,并且接受 std::shared_ptr<Functor>
。当线程结束时,智能指针将被删除。
缺点:失去了使用仿函数的好处,因为您必须指定成员函数。
需要让这个 Functor 和我的线程一样长,所以我为它创建了一个 shared_ptr 并试图将它传递给 std::thread。我已经在此处复制了代码和错误列表。
struct Functor
{
std::string greeting;
explicit Functor(std::string _greeting="Hello!"): greeting { _greeting } {}
void operator()()
{
std::cout << greeting << "\n";
}
};
auto main() ->int
{
std::shared_ptr<Functor> fp = std::make_shared<Functor> ();
std::thread t(&fp);
t.join();
return 0;
}
错误列表:
Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)' std_threads C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\thr\xthread 240
Error C2672 'std::invoke': no matching overloaded function found std_threads C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\thr\xthread 240
我是 c++11 和并发的新手。请帮助我理解以下内容
1>当按值传递时,std::thread 是否总是在对象内部调用 operator()?如果是,为什么这么定义。
2>如何确保提供给线程的资源与线程一样长?
3>这里写的Functor是函数对象吗?
4>我在这段代码中做了什么?!
1>does a std::thread always invoke the operator() inside an object when passed by value ? If so, why it has been defined so.
std::thread
调用 std::invoke
。来自 cppreference,如果第一个参数既不是 pointer to member function
也不是 pointer to data member
;它被视为一个函数对象。
因此,将调用 fp()。
INVOKE(f, t1, t2, ..., tN) is equivalent to f(t1, t2, ..., tN) (that is, f is a FunctionObject)
所以你基本上可以做到std::thread t{*fp}
2>how to ensure that a resource given to a thread stays around as long as the thread does?
您可以 shared_ptr
提供共享对象的所有权。或者您可以通过确保传递的资源在范围内来手动执行此操作。里程不同。
3>is the Functor written here, a function object ?
是的。 FunctionObject 类型是可以在函数调用运算符左侧使用的对象类型。但是 fp
不是。但是 *fp
是。
4>What have I done here in this code ?!
您可以通过显式传递带有参数 fp.get()
的 Functor::operator()
来使其工作。当然,一个简单的方法就是传递 *fp
std::shared_ptr<Functor>
不可调用 - 它不实现 operator()
,即使 Functor
实现。
这里shared_ptr
的目的是什么?为什么不干脆
int main() {
Functor f;
std::thread t(std::ref(f));
t.join();
return 0;
}
如果出于某种原因您坚持让 Functor
实例由 shared_ptr
管理,这是一种方法:
int main() {
std::shared_ptr<Functor> fp = std::make_shared<Functor> ();
std::thread t([fp]() { (*fp)(); });
t.join();
return 0;
}
您仍然可以使用以下语法让 std::thread
取得您的智能指针的所有权:
std::shared_ptr<Functor> f = std::make_shared<Functor>();
std::thread thread (&Functor::operator(), f);
thread.detach();
如果第一个参数是成员函数指针,那么第二个参数应该是对 class 实例的引用或指针,并且接受 std::shared_ptr<Functor>
。当线程结束时,智能指针将被删除。
缺点:失去了使用仿函数的好处,因为您必须指定成员函数。