Ruby多进程同步

时间:2019-04-17 04:42:54

标签: ruby process synchronization

我有一段处理多个文件的红宝石代码。大致是这样的,

1)check the 'done' json file to ignore files which have already been processed.
2)Pick up a file from remaining files to process
3)process the file
4)write a entry in 'done' file
5)repeat

我正在尝试使其在多进程环境中运行,目标是在不同的shell中多次运行ruby文件。

我遇到的第一个问题是在第1部分。当多个进程试图获取下一个要处理的文件时,就有一个竞争条件。也就是说,当条目不在“ done”文件中时,则多个进程可以接管。要处理的文件相同。(为此,我引入了.lock文件)

另外,一个进程需要知道另一个进程当前正在处理哪个文件,因此也要忽略它。(为此,我引入了一个“并发文件”)

现在我的算法看起来像这样,

1)wait for the .lock file to be not there
2)create the .lock file
3)read and ignore the files listed in the 'done' file
4)read and ignore the files listed in the 'concurrent' file
5)choose a file to process
6)write a entry in the 'concurrent' file
7)delete the .lock file
8)process the file
9)remove the entry from 'concurrent' file
10)add a entry in 'done' file
11)repeat

现在它似乎可以工作,直到我开始创建5个以上的进程。

经过一点调试之后,我发现多个进程正在同时创建.lock文件。

这是我的同步代码,

def wait_for_key
  loop do
    if File.exists? "#{file_path}/.lock"
      puts "waiting for lock to be released"
      sleep 1
    else
      break
    end
  end
end

def lock
  FileUtils.touch "#{file_path}/.lock"
  puts "download method locked #{Time.now}"
end

def release_lock
  FileUtils.rm "#{file_path}/.lock"
  puts "lock released #{Time.now}"
  sleep 1
end

所以并发算法大致是这样运行的,

wait_for_key
lock
.....do some stuff 
release_lock

因此,如果多个进程同时命中lock方法,似乎wait_for_key方法中存在竞争条件,即多个进程看到不存在.lock文件,而是它们同时调用了lock方法时间。

我真的不知道从这里去哪里,我看着红宝石互斥锁,但它似乎仅适用于多线程。

任何想法将不胜感激!

1 个答案:

答案 0 :(得分:0)

  1. 您可以确定之前需要处理哪些文件。

  2. 如果您可以访问Redis服务器,则将这些文件名放入Redis列表中,然后生成子进程,让它们一次弹出一个文件名并进行处理,直到列表为空。如果您无权访问Redis,则可以将文件平均分配给子进程。无论哪种情况,都不需要全局锁或互斥锁。