ruby - Ruby 多进程同步
问题描述
我有一段处理多个文件的 ruby 代码。它的工作原理大致是这样的,
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 部分。当多个进程试图获取下一个要处理的文件时存在竞争条件。也就是当条目不在“完成”文件中时,多个进程可以获取同一个文件处理。(为此我引入了一个 .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 方法。
我真的不知道从哪里开始,我研究了 ruby mutex 但它看起来只适用于多个线程。
任何想法将不胜感激!
解决方案
您可以在生成子进程之前确定需要处理哪些文件。
如果您可以访问 Redis 服务器,则将这些文件名放入 Redis 列表中,然后生成子进程并让它们一次弹出一个文件名并进行处理,直到列表为空。如果您无权访问 Redis,则可以将文件平均分配给子进程。在这两种情况下,您都不需要全局锁或互斥锁。
推荐阅读
- android - gradle profiler 中的不同缓存策略
- javascript - 如何从 JSON 数据中为每个对象创建一个页面 - JavaScript
- python - 使用来自 win32com 的数据向 Excel 提供命名冲突 (_FilterDatabase)
- reactjs - 如果由另一个组件渲染,延迟路由组件将不起作用
- django - 在多站点 nginx 服务器的子文件夹中访问 django 站点(默认主页有效,而不是管理员)
- terraform - 使用 for 或 For_each 循环 | 地形 0.12
- .net-core - 使用 docker-compose 运行 dotnet docker 容器
- bash - bash script.sh -b -p 目录中 -b 和 -p 的含义
- javafx - 在 JAVAFX 11 FXML 中导入 java.lang.String 失败
- mongodb - 项目反应堆和服务器端事件