根据C++ 0x最终草案,没有办法请求线程终止.也就是说,如果需要,我们需要实施一个自己动手的解决方案.
另一方面,boost :: thread提供了一种以安全方式中断线程的机制.
在您看来,什么是最好的解决方案?设计自己的合作"中断机制"还是本土的?
以下单例实现数据 - 竞争是免费的吗?
static std::atomic<Tp *> m_instance;
...
static Tp &
instance()
{
if (!m_instance.load(std::memory_order_relaxed))
{
std::lock_guard<std::mutex> lock(m_mutex);
if (!m_instance.load(std::memory_order_acquire))
{
Tp * i = new Tp;
m_instance.store(i, std::memory_order_release);
}
}
return * m_instance.load(std::memory_order_relaxed);
}
Run Code Online (Sandbox Code Playgroud)
是std::memory_model_acquire
了负载运行的多余?是否可以通过将它们切换到进一步放宽加载和存储操作std::memory_order_relaxed
?在这种情况下,获取/释放语义是否std::mutex
足以保证其正确性,或者std::atomic_thread_fence(std::memory_order_release)
还需要确保构造函数的内存写入在轻松存储之前发生?然而,使用栅栏相当于有商店memory_order_release
吗?
编辑:感谢John的回答,我提出了以下应该是数据竞争的实现.尽管内部负载可能完全是非原子的,但我决定放弃一个宽松的负载,因为它不会影响性能.与总是具有获取存储器顺序的外部负载相比,thread_local机器提高了访问大约一个数量级的实例的性能.
static Tp &
instance()
{
static thread_local Tp *instance;
if (!instance &&
!(instance = m_instance.load(std::memory_order_acquire)))
{
std::lock_guard<std::mutex> lock(m_mutex);
if (!(instance = m_instance.load(std::memory_order_relaxed)))
{
instance = new Tp;
m_instance.store(instance, std::memory_order_release);
}
}
return …
Run Code Online (Sandbox Code Playgroud) C++中多线程和异常安全之间的紧张关系是什么?是否有良好的指导方针?线程是否因未捕获的异常而终止?
假设你有一个模板类的c ++ 0x std :: array成员,你想通过一个带有几个迭代器的构造函数来初始化它:
template <typename Tp, size_t N>
class Test
{
public:
template <typename Iterator>
Test(Iterator first, Iterator last)
{
if (std::distance(first,last) > N )
throw std::runtime_error("bad range");
std::copy(first, last, _M_storage.begin());
}
private:
std::array<Tp, N> _M_storage;
};
Run Code Online (Sandbox Code Playgroud)
假设您提供了与存储大小相同的范围,是否可以在构造函数初始化程序中初始化std :: array,从而避免存储中Tps的超级默认构造函数?在这种情况下是否可以利用std :: initializer_list <>?
以下代码段有什么问题?
#include <tr1/functional>
#include <functional>
#include <iostream>
using namespace std::tr1::placeholders;
struct abc
{
typedef void result_type;
void hello(int)
{ std::cout << __PRETTY_FUNCTION__ << std::endl; }
void hello(int) const
{ std::cout << __PRETTY_FUNCTION__ << std::endl; }
abc()
{}
};
int
main(int argc, char *argv[])
{
const abc x;
int a = 1;
std::tr1::bind(&abc::hello, x , _1)(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尝试用 g++-4.3 编译它,似乎cv -qualifier 重载函数混淆了两者tr1::mem_fn<>
,tr1::bind<>
并出现以下错误:
no matching function for call to ‘bind(<unresolved overloaded function type>,...
Run Code Online (Sandbox Code Playgroud)
相反,以下代码段可以编译,但似乎破坏了const-correctness …
假设您有一个元组,并希望通过对第一个类型的每种类型应用元函数来生成新元组.什么是最有效的C++元功能来完成这项任务?是否也可以使用C++ 0x可变参数模板来提供更好的实现?
我有一个带有成员函数的类,它接受一个默认参数.
struct Class
{
void member(int n = 0)
{}
};
Run Code Online (Sandbox Code Playgroud)
通过std :: tr1 :: mem_fn,我可以调用它:
Class object;
std::tr1::mem_fn(&Class::member)(object,10);
Run Code Online (Sandbox Code Playgroud)
也就是说,如果我想用默认参数调用对象上的可调用成员,那么正确的语法是什么?
std::tr1::mem_fn(&Class::member)(object); // This does not work
Run Code Online (Sandbox Code Playgroud)
g ++抱怨以下错误:
test.cc:17: error: no match for call to ‘(std::tr1::_Mem_fn<void (Class::*)(int)>) (Class&)’
/usr/include/c++/4.3/tr1_impl/functional:551: note: candidates are: _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class&, _ArgTypes ...) const [with _Res = void, _Class = Class, _ArgTypes = int]
/usr/include/c++/4.3/tr1_impl/functional:556: note: _Res std::tr1::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)>::operator()(_Class*, _ArgTypes ...) const [with _Res = void, _Class = Class, _ArgTypes …
Run Code Online (Sandbox Code Playgroud)