3

客观的

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

免责声明

  • 不想为此使用任何外部依赖项
  • 不允许使用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

附带问题:

  • 我应该使用单个互斥锁吗?
  • 每个工人创建自己的互斥体是否重要?
4

2 回答 2

2

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

同样,每个进程都有自己的互斥体副本,因此同步调用不会实现任何目标。

如果您需要与子进程通信,一种方法是使用管道(请参阅 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 中没有内置跨进程并发原语。

于 2013-07-11T07:12:38.227 回答
1

File 类flock可以让你锁定一个文件。这是进行进程间锁定的一种方法。

remote_lock如果您想远程存储它,甚至可以调用一个 gem 。

于 2016-12-04T04:39:03.997 回答