Ruby Multi-Process Synchronization - PullRequest
       7

Ruby Multi-Process Synchronization

0 голосов
/ 17 апреля 2019

У меня есть фрагмент кода 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

Я пытаюсь запустить его в многопроцессорной среде, цель состоит в том, чтобы запустить файл 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

Таким образом, если несколько процессов одновременно обращаются к методу блокировки, кажется, что в методе wait_for_key есть условие состязания. То есть несколько процессов видят, что файл .lock отсутствует, чем они вызывают метод блокировки одновременно время.

Я действительно не знаю, куда идти отсюда, я заглянул в ruby ​​mutex, но похоже, что он работает только для нескольких потоков.

Будут оценены любые идеи!

1 Ответ

0 голосов
/ 17 апреля 2019
  1. Вы можете определить, какие файлы должны быть обработаны до создания дочерних процессов.

  2. Если у вас есть доступ к серверу Redisзатем поместите эти имена файлов в список Redis, а затем порождайте дочерние процессы и позволяйте им извлекать по одному имени за раз и обрабатывать его, пока список не станет пустым.Если у вас нет доступа к Redis, вы можете равномерно назначить файлы дочерним процессам.Ни в том, ни в другом случае вам не требуется глобальная блокировка или мьютекс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...