Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 3 Rails并发问题-如何使用锁_Ruby On Rails 3_Concurrency - Fatal编程技术网

Ruby on rails 3 Rails并发问题-如何使用锁

Ruby on rails 3 Rails并发问题-如何使用锁,ruby-on-rails-3,concurrency,Ruby On Rails 3,Concurrency,我有一个lib类(“Updater”),它可以执行一些长任务,这些任务可以手动(在浏览器中)启动,也可以每2小时启动一次(我已经实现了where gem,它每2小时执行一次计划) 看到这个任务在数据库上做了很多工作,我认为可能会发生一些并发错误(例如,如果调用when还可以工作)。 我说得对吗 我想到了一个使用互斥体的解决方案,为我的更新程序类提供了一个伪代码,如下所示: module Updater def start #do some job end end 我认为,一个正

我有一个lib类(“Updater”),它可以执行一些长任务,这些任务可以手动(在浏览器中)启动,也可以每2小时启动一次(我已经实现了where gem,它每2小时执行一次计划)

看到这个任务在数据库上做了很多工作,我认为可能会发生一些并发错误(例如,如果调用when还可以工作)。 我说得对吗

我想到了一个使用互斥体的解决方案,为我的更新程序类提供了一个伪代码,如下所示:

module Updater
  def start
    #do some job
  end
end
我认为,一个正确的解决方案是这样的

module Updater
  def start
    mutex.lock
       #do some job
    mutex.unlock
  end
end
我的解决方案正确吗

请提供一些关于并发的更多信息(例如如何在Rails中正确使用互斥,我需要什么,等等)?
我已经搜索过了,但没有找到合理的解释。

我认为正确的使用a的方法是获得锁,运行代码块,然后再次释放锁,即结合使用lock和unlock

@mutex = Mutex.new
..

def start
  @mutex.lock
  begin
    ..
  ensure
    @mutex.unlock rescue nil
  end
end
或使用同步方法:

@mutex = Mutex.new
..

def start
  @mutex.synchronize do
    # do something
  end
end
可以在Rack Middleware类中找到一个示例。但我不确定它在您的情况下是否有用,即使您使用类变量,如
@@mutex
,因为互斥/信号量可能不会在不同的任务和不同的进程之间保留(我假设“任务”是由“rake任务”启动的不同进程)。互斥类对于实现线程安全非常有用,因为它实现了一个简单的信号量,可用于协调对来自多个并发线程的共享数据的访问。然而,也有一个好的(不幸的是,只有在付费墙后面)


在您的情况下,在数据库中创建全局锁标志可能会有所帮助,或者使用
touch lock.txt
在文件系统中创建全局锁文件,并在进程结束时使用
rm lock.txt
再次删除该文件。可以使用Kernel.system或%x执行这些命令。如果文件存在
file.exists?(“lock.txt”)
则可以暂停更新

+1谢谢你的回答!我将按照您的建议尝试,希望它能与不同的流程协同工作;)