我开始使用命名空间中的unordered_set类tr1来加速对普通(基于树的)STL的访问map.但是,我想在boost(boost::thread::id)中存储对线程ID的引用,并意识到这些标识符的API是如此不透明,以至于您无法清楚地获得它的哈希值.
令人惊讶的是,boost实现了tr1(包括hash和unordered_set)的一部分,但它没有定义能够散列线程ID的哈希类.
查看boost::thread::id我发现的文档,发现线程ID可以输出到流,所以我的哈希解决方案是:
struct boost_thread_id_hash
{
size_t operator()(boost::thread::id const& id) const
{
std::stringstream ostr;
ostr << id;
std::tr1::hash<std::string> h;
return h(ostr.str());
}
};
Run Code Online (Sandbox Code Playgroud)
也就是说,序列化它,将哈希应用于结果字符串.但是,这似乎比实际使用STL效率低map<boost::thread::id>.
所以,我的问题:您是否找到了更好的方法?在boost和tr1中是否明显不一致而不强迫hash<boost::thread::id>类的存在?
谢谢.
我目前在单线程应用程序中运行来自其他人库的函数Foo.大多数时候,我打电话给Foo并且它很快,有时候,我打电话给Foo并且它需要永远.我不是一个耐心的人,如果Foo要永远服用,我想停止执行Foo而不是用这些参数调用它.
以受控方式调用Foo的最佳方法是什么(我当前的环境是POSIX/C++),这样我可以在一定的秒数后停止执行.我觉得在这里做正确的事情就是创建第二个线程来调用Foo,而在我的主线程中我创建了一个计时器函数,如果它没有时间,它最终将发出第二个线程的信号.
还有另一个更贴切的模型(和解决方案)吗?如果没有,Boost的Signals2库和Threads会不会这样做?
使类线程安全的直接方法是添加互斥锁属性并在访问器方法中锁定互斥锁
class cMyClass {
boost::mutex myMutex;
cSomeClass A;
public:
cSomeClass getA() {
boost::mutex::scoped_lock lock( myMutex );
return A;
}
};
Run Code Online (Sandbox Code Playgroud)
问题是这使得该类不可复制.
我可以通过使互斥锁成为静态来使事情发挥作用.但是,这意味着当访问任何其他实例时,类的每个实例都会阻塞,因为它们都共享相同的互斥锁.
我想知道是否有更好的方法?
我的结论是没有更好的方法.使用私有静态互斥锁属性创建一个线程安全的类是"最好的": - 它很简单,它有效,它隐藏了尴尬的细节.
class cMyClass {
static boost::mutex myMutex;
cSomeClass A;
public:
cSomeClass getA() {
boost::mutex::scoped_lock lock( myMutex );
return A;
}
};
Run Code Online (Sandbox Code Playgroud)
缺点是类的所有实例共享相同的互斥锁,因此不必要地相互阻塞.这不能通过使互斥属性非静态(因此为每个实例赋予其自己的互斥锁)来解决,因为如果正确完成,复制和赋值的复杂性是噩梦般的.
如果需要,各个互斥锁必须由外部不可复制的单例管理,并在创建时为每个实例建立链接.
感谢所有的回复.
有几个人提到编写我自己的复制构造函数和赋值运算符.我试过这个.问题是我的真正的类具有许多在开发期间总是在变化的属性.维护复制构造函数和assignmet运算符是繁琐且容易出错的,错误导致难以发现错误.让编译器为复杂类生成这些是一个巨大的节省时间和bug减少器.
许多响应都关注使复制构造函数和赋值运算符是线程安全的.这个要求为整个事情增加了更多的复杂性!幸运的是,我不需要它,因为所有复制都是在单个线程中进行设置时完成的.
class cSafe {
boost::mutex myMutex;
cSomeClass A;
public:
cSomeClass getA() {
boost::mutex::scoped_lock lock( myMutex );
return A;
}
(copy constructor)
(assignment op )
};
class cMyClass …Run Code Online (Sandbox Code Playgroud) (这个问题虽然相似,但并没有真正回答我的问题.)
我在自己的"线程组"实现方面遇到了问题,并且没有更接近解决甚至找出问题,我正在考虑使用boost::thread_grp.
现在,根据我在主题1 上可以找到的文档,我一直认为线程对象 - 无论其实际工作的持续时间 - 仍然存在并且是线程组的一部分,直到线程组被销毁.
但是,粗略的测试似乎表明,boost::thread_group::size()当线程完成其工作并终止时,它自己会减少.这意味着线程对象本身也正在为我清理.
这是真的?我可以依靠它吗?
#include <cassert>
#include <unistd.h> // for sleep()
#include <boost/thread.hpp>
boost::mutex m;
unsigned int count = 0;
void func() {
boost::mutex::scoped_lock l(m);
count++;
}
int main()
{
boost::thread_group grp;
for (size_t i = 0; i < 300; i++)
grp.create_thread(func());
sleep(10);
assert(count == 300);
assert(grp.size() == 0); // passes, in my tests
// ^ Can I rely on that? …Run Code Online (Sandbox Code Playgroud) 我正在尝试编译我的程序但它根本不会链接.我已经指定了boost lib文件的路径,链接器仍然抱怨.这是我得到的链接错误:
1>Edproj.obj : error LNK2001: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::system_category(void)" (?system_category@system@boost@@YAABVerror_category@12@XZ)
1>Edproj.obj : error LNK2001: unresolved external symbol "class boost::system::error_category const & __cdecl boost::system::generic_category(void)" (?generic_category@system@boost@@YAABVerror_category@12@XZ)
1>Edproj.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall boost::detail::thread_data_base::~thread_data_base(void)" (??1thread_data_base@detail@boost@@UAE@XZ)
1>Edproj.obj : error LNK2001: unresolved external symbol "void __cdecl boost::throw_exception(class std::exception const &)" (?throw_exception@boost@@YAXABVexception@std@@@Z)
1>Edproj.obj : error LNK2001: unresolved external symbol "public: void __thiscall boost::thread::detach(void)" (?detach@thread@boost@@QAEXXZ)
1>Edproj.obj : error LNK2001: unresolved external symbol "public: void __thiscall boost::thread::join(void)" (?join@thread@boost@@QAEXXZ) …Run Code Online (Sandbox Code Playgroud) 我是Boost.Threads的新手,我正在尝试理解如何将函数参数传递给boost::thread_groups::create_thread()函数.在阅读了一些教程和boost文档之后,我明白可以简单地将参数传递给这个函数,但是我无法使这个方法起作用.
我读到的另一个方法是使用函子将参数绑定到我的函数但是会创建参数的副本,我严格要求传递const引用,因为参数将是大矩阵(我计划通过使用boost::cref(Matrix)一次我得到这个简单的例子来工作).
现在,让我们来看看代码:
void printPower(float b, float e)
{
cout<<b<<"\t"<<e<<"\t"<<pow(b,e)<<endl;
boost::this_thread::yield();
return;
}
void thr_main()
{
boost::progress_timer timer;
boost::thread_group threads;
for (float e=0.; e<20.; e++)
{
float b=2.;
threads.create_thread(&printPower,b,e);
}
threads.join_all();
cout << "Threads Done" << endl;
}
Run Code Online (Sandbox Code Playgroud)
这不会编译与以下错误:
mt.cc: In function âvoid thr_main()â:
mt.cc:46: error: no matching function for call to âboost::thread_group::create_thread(void (*)(float, float), float&, float&)â
/usr/local/boost_1_44_0/include/boost/thread/detail/thread.hpp: In member function âvoid boost::detail::thread_data<F>::run() [with F = void (*)(float, float)]â:
mt.cc:55: instantiated from here
/usr/local/boost_1_44_0/include/boost/thread/detail/thread.hpp:61: …Run Code Online (Sandbox Code Playgroud) 为了开始boost::thread,我写了一个非常简单的例子 - 它不起作用.有谁可以指出我的错误?
我写了一个非常简单的仿函数类来完成这项工作.它应该计算一个std::vector双精度的总和,并给我一个方法来获得后来的结果:
class SumWorker
{
private:
double _sum;
public:
SumWorker() : _sum(-1.0) {}
void operator() (std::vector<double> const & arr)
{
_sum = 0.0;
for(std::vector<double>::const_iterator i = arr.begin();
i != arr.end();
i++)
{
_sum += (*i);
}
}
double const value() const
{
return _sum;
}
};
Run Code Online (Sandbox Code Playgroud)
现在,我可以通过两种方式之一计算总和.如果我在主线程中这样做,比如,
SumWorker S;
S(numbers); // "numbers" is an std::vector<double>
double sum = S.value(); // "sum" now contains the sum
Run Code Online (Sandbox Code Playgroud)
一切正常.但是,如果我尝试在一个单独的线程中执行此操作(这是重点),
SumWorker S;
boost::thread thread(S, numbers); // Should be …Run Code Online (Sandbox Code Playgroud) 根据http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/overview/cpp2011/futures.html,我们可以使用boost :: asio std::future.但我找不到任何有关使用的信息boost::unique_future,它有更多的功能,例如then().我该怎么用?
所以我使用a boost::lockfree::spec_queue通过两个boost_threads在我的应用程序中运行两个对象的仿函数进行通信.
一切都很好,除了spec_queue::pop()方法是非阻塞的事实.即使队列中没有任何内容,它也会返回True或False.但是我的队列似乎总是返回True(问题#1).我想这是因为我预先分配了队列.
typedef boost::lockfree::spsc_queue<q_pl, boost::lockfree::capacity<100000> > spsc_queue;
Run Code Online (Sandbox Code Playgroud)
这意味着要有效地使用队列,我必须忙着等待不断使用100%cpu弹出队列.我宁愿不睡任意的时间.我已经在java中使用了其他队列,直到对象可用为止.这可以用std ::或boost :: data结构来完成吗?
用法:在我们的生产中,我们有大约100个线程,可以访问我们试图实现的缓存.如果错过了缓存,则将从数据库中获取信息,并且将通过编写器线程更新缓存.
为此,我们计划实现multiple read and single writer我们无法更新g ++版本,因为我们正在使用g++-4.4
更新:每个工作线程都可以用于读取和写入.如果错过了缓存,则从DB缓存信息.
问题陈述: 我们需要实现缓存以提高性能.为此,缓存读取更频繁,对缓存的写入操作非常少.
我觉得可以用boost::shared_mutex boost::shared_lock,boost::upgrade_lock,boost::upgrade_to_unique_lock implementation
但我们了解到boost::shared_mutex存在性能问题:
问题
boost::shared_mutex在读取的情况下是否会影响性能?g++4.4?reads are lock free?此外,我们还打算用来Map保存缓存信息.
boost-thread ×10
c++ ×10
boost ×3
boost-asio ×1
hash ×1
lock-free ×1
visual-c++ ×1
watchdog ×1