如何使用分叉的Ruby进程进行进程间锁定



目标

使用Ruby的fork方法和几个工人增加计数器

免责声明

  • 我不想使用任何外部依赖项
  • 不允许使用Ruby的Thread
  • 我想看看使用fork是否可行

这里有一个小的共享内存模拟

class Memory
  def self.address= value
    @value = value
  end
  def self.address
    @value
  end
end

这是我的员工

class Worker
  def initialize mutex
    @mutex = mutex
  end
  def work
    @mutex.synchronize do
      print "begin: %d " % (tmp=Memory.address)
      sleep 0.05
      print "end: %d n" % (Memory.address = tmp + 1)
    end
  end
end

让我们运行

# init
Memory.address = 0
mutex = Mutex.new
# create workers
workers = []
10.times do
  workers << fork do
    Worker.new(mutex).work
  end
end
# wait for workers to finish
Process.waitall

输出

begin: 0 begin: 0 begin: 0 begin: 0 begin: 0 begin: 0 begin: 0 begin: 0 begin: 0 begin: 0 end: 1
end: 1
end: 1
end: 1
end: 1
end: 1
end: 1
end: 1
end: 1
end: 1

预期输出

begin: 0 end: 1
begin: 1 end: 2
begin: 2 end: 3
begin: 3 end: 4
begin: 4 end: 5
begin: 5 end: 6
begin: 6 end: 7
begin: 7 end: 8
begin: 8 end: 9
begin: 9 end: 10

附带问题:

  • 我应该用一个Mutex吗
  • 每个工人创建自己的Mutex有关系吗

分叉进程继承其父进程的资源,但内存是一个副本(或写入时的副本):在一个进程中所做的更改对其他进程没有影响。

类似地,每个进程都有自己的互斥对象副本,所以对synchronize的调用不会起到任何作用。

如果您需要与子进程通信,一种方法是使用管道(请参阅IO文档)。每个进程都继承管道的一个副本,并且来自一个进程的写入将显示在另一个进程中。

child_in, parent_out = IO.pipe
parent_in, child_out = IO.pipe
Process.fork do
  parent_out.close
  parent_in.close
  #data written to child_out appears on parent_in in the parent process
  #reading from child_in returns data the parent has written to parent_out
end
child_out.close
child_in.close
#write data to parent_out here to have it appear on child_in in the child
#reading from parent_in to get data the child has written to child_out

据我所知,ruby中没有内置跨进程并发原语。

File类有flock,可以锁定文件。这是执行进程间锁定的一种方法。

如果您想远程存储,甚至还有一个名为remote_lock的gem。

最新更新