在使用多线程时,我经常遇到以下问题:
我有一个对象,比如网络接收器(但可以是任何东西)。以及获取数据的函数。现在有时根本就没有数据,你想让线程等待获取它的数据。阻塞调用,非常类似于 Berkeley 套接字及其派生实现所使用的。
原理很简单:
现在当然还有其他实现方法。但我通常使用 C++11 实现如下:
对象 A 在专用于此任务的单独线程上调用对象 B 中的函数。Object B 使用 std::condition_variable 构造来阻塞线程,直到数据被实际获取。 对象 A 将数据放入队列中,由主线程读取。现在我的实际问题出现在 object B 的销毁上,如果它必须在 object A 之前被销毁(返回 nullptr,或在阻塞调用中类似的东西).我真的不知道如何有效地包装 object B。
主要问题是 object B 不知道线程,一个线程只能有一个句柄,它在 object A 中。
示例:
一些代码来说明我的问题。
假设我在对象 B 中有这个函数:
data* getData
{
std::unique_lock<std::mutex>l_newDataWaiterLock(m_newDataWaiterMutex);
m_newDataWaiter.wait(l_newDataMutex);
if(!running)
return nullptr
else
return data;
}
和这个析构函数:
~ObjectB()
{
m_running = false;
m_newDataWaiter.notifyAll();
//Point X
}
使用这些成员变量:
std::condition_variable m_newDataWaiter;
std::atomic<bool> m_running;
我们仍然有析构函数必须在指示的 Point X 等待的问题,直到所有其他线程都收到通知并返回 null。
现在我可以使用原子计数器、更多 std::condition_variable 和互斥锁来做一些事情。但我觉得必须有一个更优雅、更可靠的解决方案来解决这个问题:)。因为此解决方案需要在 object B 的整个生命周期的每个 getData 调用中进行通知。
注意:我使用的是 C++11,所以我用它来说明一切。我希望用它来解决它。虽然这当然是一个更普遍的并发问题。
最佳答案
用 std::shared_ptr 管理对象 B 怎么样?并使用 std::weak_ptr将指针存储在 A 中?
每次 A 想要获得访问权限时,效率会稍微低一些,它暂时需要通过 std::weak_ptr::lock() 获得一个 std::shared_ptr本身,但您可以确定不再存在竞争条件。
关于c++ - 强制线程在销毁前离开对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30241005/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
Arel3.0.2提供了两个类来指定连接类型:Arel::Nodes::InnerJoin和Arel::Nodes::OuterJoin并使用InnerJoin默认。foo=Arel::Table.new('foo')bar=Arel::Table.new('bar')foo.join(bar,Arel::Nodes::InnerJoin)#innerfoo.join(bar,Arel::Nodes::OuterJoin)#outerfoo.join(bar,???)#left如果要生成左连接,如何连接两个表? 最佳答案 你可以使用
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser