Общий список / карта из нескольких тем в F #? - PullRequest
4 голосов
/ 15 июня 2010

Я делаю программу для обработки множества блокирующих операций ввода-вывода, порождая агента / MailboxProcessor для каждой операции.У меня есть куча файлов, которые я кэшировал в памяти на карте, и я хочу поделиться ими с этими агентами.Тем не менее, у меня также есть FileSystemWatcher для обратного вызова всякий раз, когда в файлы вносятся изменения, так что я могу обновить кеш.

Как мне сделать так, чтобы не допустить повреждения кеша многопоточным чтениеми напишите?

Мне кажется, что карта уже основана на указателях на объекты, так что это автоматически решит мою проблему, поскольку я просто меняю указатели на новые объекты по мере их загрузки илиэто нарушенное понимание этого?

Спасибо

Ответы [ 3 ]

3 голосов
/ 15 июня 2010

Мне кажется, что карта уже основана на указателях на объекты, поэтому это автоматически решит мою проблему, поскольку я просто меняю указатели на новые объекты по мере их загрузки, или это неверное понимание

Я думаю, что вы понимаете правильно. У вас может быть только одна изменяемая ссылка на неизменяемую карту. Запись новой карты в ссылку является атомарной, поэтому синхронизировать ее не нужно.

1 голос
/ 15 июня 2010

Когда я видел похожие программы на Erlang, системы настраивались следующим образом:

  • Вы можете заключить FileSystemWatcher в MailboxProcessor, чтобы обрабатывать входящие обновлениякак сообщения, а не события Windows.Ваш FileSystemWatcherProcess может содержать список детей, которые слушают, и выкладывать обновления по мере необходимости.Это в основном то же самое, что и программирование на основе событий, только с сообщениями и акторами.

    Ваш FileSystemWatcherProcess не должен поддерживать ваш кэш файлов, он просто слепо выталкивает сообщения.

  • ИЛИ У вас есть мастер-процесс, который хранит состояние карты.Файл SystemWatcher отправляет обновления мастеру.Каждый дочерний поток содержит ссылку на мастер, поэтому каждый раз, когда они заканчивают обработку элемента или пакета элементов, они отправляют сообщение в мастер-процесс с запросом последней карты.

Ни то, ни другоеСистема требует блокировки.

0 голосов
/ 16 июня 2010

После ответа Джона. если у вас несколько писателей, вместо блокировок вы всегда можете сделать CAS:

 let updateMap value =
    let mutable success = false
    while not success do
      let v = !x
      let result = Interlocked.CompareExchange(x, v.Add(value), v)
      success <- Object.ReferenceEqual(v, result)

И, если вам подойдет таргетинг только на .Net 4.0, вам не следует изобретать все это самостоятельно: существует класс System.Collections.Concurrent.ConcurrentDictionary, который уже реализует одновременно читаемый и записываемый словарь.

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