先介绍一下应用场景:
我有一个服务应用程序正在监视某物的状态,同时还有多个应用程序正在等待状态更改。一旦状态发生变化,每个应用程序将读取状态值(通过命名的 FileMap 对象)并执行相应的操作,然后等待状态再次发生变化。
所以我使用了一个命名的事件对象来做同步工作。所有应用程序都在等待此事件被发出信号,并且服务应用程序将设置此事件以在该状态更改时被发出信号。
我需要保证当状态改变时,每个等待的申请都会被释放并且只被释放一次!
这两种方法我都试过了
这两种方法在测试过程中似乎都很有效。但我认为它们都不可靠,因为:
对于##方法1 ##,在调用ResetEvent函数之前,可能一些等待线程没有机会执行。
对于##方法2##,微软声称PulseEvent is unreliable and should not be used .
这个案例有什么可行的解决方案吗?欢迎任何建议。
最佳答案
无法使用 O(1) 同步原语安全地实现这一点。
要通知 N 个应用程序有关新的状态更改,请使用 N 个事件。服务应设置它们,每个应用程序应在处理当前状态更改时重置其相应的事件。
要等待所有应用程序处理新的状态更改服务,可以使用另一组 N 个事件和带有 bWaitAll==TRUE 的 WaitForMultipleObjects。每个应用程序都应该设置它对应的事件。
因此,服务执行一个循环:观察状态变化,写入共享内存,设置所有 A 事件,等待所有 B 事件,重置所有 B 事件,继续循环。每个应用程序都执行一个循环:WAITING其 A(i) 事件、重置 A(i)、处理状态更改、设置 B(i)、继续循环。
A事件和B事件都可以是自动复位类型。然后您无需重置任何内容。
如果您觉得环保并且不想浪费资源,您可以使用某种反向信号量来代替 B 组事件。这可以通过一个由互斥量同步的共享计数器和一个通知服务的事件 (B') 来实现。服务不会等待整个 B 集,而是等待 B',当等待结束时将计数器设置为 N。每个应用程序不应设置其 B(i) 事件,而是应递减计数器,如果计数器降为零,则最后一个应用程序应仅设置 B'。
您无法绕过 A 组事件。问题不在于设置 A 事件,而在于重置。通过重置其 A(i) 事件,应用程序将不会错过另一个状态更改。并且在这里使用信号量也没有帮助。
请注意,此解决方案未考虑应用程序可能崩溃的情况。如果发生这种情况,该服务将永远等待不存在的应用程序响应。
关于windows - 关于 Win32 ##Event## 同步对象的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4322193/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?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变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=