【发布时间】:2015-01-03 05:13:28
【问题描述】:
我希望按照this answer 的思路在 C++11 中实现一个“可中断”线程。
我已经参数化了我的可中断类,以便它可以包装任何具有类似构造函数的线程类(用于 std::thread,但也应该适用于 boost::thread 之类的东西(没关系 boost::thread 已经有这个功能))。那部分应该无关紧要。
尽管链接的答案有一些我必须纠正的问题,但这对我来说很有意义,所以我想弄清楚我哪里出错了。
我已经包含了相关的来源和结果。
interruptible.hpp
#include <atomic>
#include <exception>
#include <thread>
class interrupted_exception : public virtual std::exception
{
public:
char const *what() const noexcept { return "interrupted"; }
};
template <typename T>
class interruptible
{
public:
template <typename F, typename... A>
interruptible(F&& Function, A&&... Arguments) :
Interrupted(false),
Thread(
[](std::atomic_bool *Interrupted, F&& Function, A&&... Arguments)
{
LocalInterrupted = Interrupted;
Function(std::forward<A>(Arguments)...);
},
&this->Interrupted,
std::forward<F>(Function),
std::forward<A>(Arguments)...
)
{ }
void interrupt() { this->Interrupted = true; }
bool interrupted() const { return this->Interrupted; }
T *operator->() { return &this->Thread; }
static inline void check() noexcept(false)
{
if (!interruptible::LocalInterrupted)
return;
if (!interruptible::LocalInterrupted->load())
return;
throw interrupted_exception();
}
private:
static thread_local std::atomic_bool *LocalInterrupted;
std::atomic_bool Interrupted;
T Thread;
};
template <typename T>
thread_local std::atomic_bool *interruptible<T>::LocalInterrupted = nullptr;
main.cpp
#include <iostream>
#include <unistd.h>
#include <thread>
#include "interruptible.hpp"
void DoStuff()
{
try
{
while (true)
{
std::cout << "Loop" << std::endl;
sleep(1);
interruptible<std::thread>::check();
}
}
catch (interrupted_exception const &e)
{
std::cout << "Interrupted!" << std::endl;
}
}
int main()
{
interruptible<std::thread> a(DoStuff);
sleep(2);
std::cout << "Interrupting..." << std::endl;
a.interrupt();
sleep(2);
a->join();
return 0;
}
当我用 g++ -std=c++11 main.cpp (gcc 4.9.2) 编译它时,我得到:
/usr/include/c++/4.9.2/functional:1665:61: error: no type named ‘type’ in ‘class std::result_of<interruptible<T>::interruptible(F&&, A&& ...) [with F = void (&)(); A = {}; T = std::thread]::<lambda(std::atomic_bool*, void (&)())>(std::atomic_bool*, void (*)())>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.9.2/functional:1695:9: error: no type named ‘type’ in ‘class std::result_of<interruptible<T>::interruptible(F&&, A&& ...) [with F = void (&)(); A = {}; T = std::thread]::<lambda(std::atomic_bool*, void (&)())>(std::atomic_bool*, void (*)())>’
_M_invoke(_Index_tuple<_Indices...>)
^
任何人都可以解决这个问题,我们将不胜感激!
【问题讨论】:
-
清理您的代码:该错误可以从减少 90% 的代码中产生。最少、完整的示例,而不是“粘贴我的代码并询问如何修复它”。
-
我将尝试将其浓缩为错误。不过,我的第一次尝试没有成功。如果您确切知道如何生成此错误,我们将不胜感激。
-
如果您同意 @t.c.简化很好地反映了问题,修改问题以匹配它。请记住,我们更关心错误而不是系统。
标签: c++ multithreading c++11 lambda perfect-forwarding