下面的示例代码将 boost::exception 对象从 1 个线程复制/传输到另一个线程,由于异常/exception_ptr 内部状态销毁期间的竞争条件而崩溃。我不确定解决它的最佳方法是什么。
使用的 boost 版本是 1.42,平台是在双核 Intel m/c 上运行的 Ubuntu lucid。编译器是 gcc 4.4.3。
#include <iostream>
#include <boost/exception/all.hpp>
#include <boost/thread.hpp>
struct Exception
: public virtual std::exception
, public virtual boost::exception
{
};
struct MyException : public virtual Exception {};
struct MyTag {};
typedef boost::error_info<MyTag, std::string> MyError;
struct Test
{
Test()
{
_t.reset(new boost::thread(boost::bind(&Test::executor, this)));
}
~Test()
{
_t->join();
}
void executor()
{
std::cerr << "executor: starting ...\n";
for (;;)
{
boost::unique_lock<boost::mutex> lk(_mx);
while(_q.empty())
{
_cv.wait(lk);
}
{
boost::shared_ptr<boost::promise<int> > pt = _q.front();
_q.pop_front();
lk.unlock();
pt->set_exception(boost::copy_exception(MyException() << MyError("test")));
}
}
}
void run_impl()
{
try
{
boost::shared_ptr< boost::promise<int> > pm(new boost::promise<int>());
boost::unique_future<int> fu = pm->get_future();
{
boost::unique_lock<boost::mutex> lk(_mx);
_q.push_back(pm);
pm.reset();
}
_cv.notify_one();
fu.get();
assert(false);
}
catch (const MyException& e)
{
throw;
}
catch (const boost::exception& )
{
assert(false);
}
catch (...)
{
assert(false);
}
}
void run()
{
std::cerr << "run: starting ...\n";
for (;;)
{
try
{
run_impl();
}
catch (...)
{
}
}
}
private:
boost::mutex _mx;
std::list< boost::shared_ptr< boost::promise<int> > > _q;
boost::shared_ptr<boost::thread> _t;
boost::condition_variable_any _cv;
};
int main()
{
Test test;
test.run();
}
/*
#0 0x080526bd in boost::exception_detail::refcount_ptr<boost::exception_detail::error_info_container>::release (this=0x806e26c) at /boost_1_42_0/boost/exception/exception.hpp:79
#1 0x0804f7c5 in ~refcount_ptr (this=0x806e26c, __in_chrg=<value optimized out>) at /boost_1_42_0/boost/exception/exception.hpp:34
#2 0x0804bb61 in ~exception (this=0x806e268, __in_chrg=<value optimized out>) at /boost_1_42_0/boost/exception/exception.hpp:254
#3 0x0805579a in ~clone_impl (this=0x806e260, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at /boost_1_42_0/boost/exception/exception.hpp:391
#4 0x001ff633 in ?? () from /usr/lib/libstdc++.so.6
#5 0x0027233d in _Unwind_DeleteException () from /lib/libgcc_s.so.1
#6 0x001fe110 in __cxa_end_catch () from /usr/lib/libstdc++.so.6
#7 0x0804f7a4 in Test::run (this=0xbffff74c) at ex_org.cpp:89
#8 0x0804b869 in main () at ex_org.cpp:106
*/
最佳答案
我不是 boost 专家,但我注意到一些竞争问题,它在 Debug模式下运行正常吗?
对于执行者我会这样写
void executor()
{
std::cerr << "executor: starting ...\n";
for (;;)
{
_cv.wait(lk);
boost::unique_lock<boost::mutex> lk(_mx);
__sync_synchronize (); // Tells the compiler to prevent optimizations
if ( !_q.empty() ) {
boost::shared_ptr<boost::promise<int> > pt = _q.front();
_q.pop_front();
pt->set_exception(boost::copy_exception(MyException() << MyError("test")));
}
}
}
还有
void run_impl()
{
try
{
boost::shared_ptr< boost::promise<int> > pm(new boost::promise<int>());
boost::unique_future<int> fu = pm->get_future();
{
boost::unique_lock<boost::mutex> lk(_mx);
// prevent the compiler from mixing above and below code
__sync_synchronize ();
_q.push_back(pm);
pm.reset();
}
_cv.notify_one();
// This one is the paranoïd's one ;), one must check without !
__sync_synchronize ();
{
// since fu must holds an internal reference pm being currently
// changed by the other thread !
boost::unique_lock<boost::mutex> lk(_mx);
// Then you are assured that everything is coherent at this point
// the stack frame holding the exception stuffs won't be corrupted
fu.get();
}
assert(false);
}
关于c++ - 跨线程复制 boost::exception 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10754530/
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
我是ruby的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:
我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id