Блокировка чтения и записи с GCD

Мое приложение сильно использует GCD, и почти все разделено небольшими задачами, обрабатываемыми диспетчерами. Однако основная модель данных в основном читается и только изредка записывается.

В настоящее время я использую блокировки для предотвращения изменений критических структур данных во время чтения. Но, посмотрев на блокировки еще сегодня, я нашел NSConditionLock и некоторую страницу о блокировках чтения и записи. Последнее - именно то, что мне нужно.

Я нашел эту реализацию: http://cocoaheads.byu.edu/wiki/locks. Мой вопрос в том, будет ли эта реализация работать с GCD, видя, что она использует PThreads?

Ответ 1

Он по-прежнему будет работать. pthreads - это API-интерфейс потоковой передачи, который лежит в основе всех других API-интерфейсов, использующих нити, в Mac OS X. (В этом случае активируются потоки Mach, но это SPI, а не API.) В любом случае блокировки pthreads на самом деле не требуют использования pthreads потоки.

Однако, GCD предлагает лучшую альтернативу iOS 5: dispatch_barrier_async(). В принципе, у вас есть приватная параллельная очередь. Вы отправляете все операции чтения на него обычным способом. Вы отправляете операции записи с помощью барьерных процедур. Та-да! Блокировка чтения-записи.

Вы можете узнать больше об этом, если у вас есть доступ к видеозаписям WWDC 2011 для сеанса 210 - Освоение Grand Central Dispatch.

Ответ 2

Вы также можете рассмотреть возможность сохранения очереди для всех операций чтения/записи. Затем вы можете dispatch_sync() записывать в эту очередь, чтобы обеспечить быстрое применение изменений в модели данных и dispatch_async() всех чтений, чтобы убедиться, что вы поддерживаете хорошую производительность в приложении.

Поскольку у вас есть одна последовательная очередь, на которой происходят все чтения и записи, вы гарантируете, что никакие чтения не могут произойти во время записи. Это намного дешевле, чем блокировка, но это означает, что вы не можете выполнять несколько операций "читать" одновременно. Это вряд ли вызовет проблему для большинства приложений.

Использование dispatch_barrier_async() может означать, что сделанные вами записи занимают произвольное количество времени, чтобы на самом деле было выполнено, поскольку все ранее существовавшие задачи в очереди должны быть выполнены до того, как ваш барьерный блок выполнит.