2013-03-21 4 views
1

Что произойдет, если вы dispatch_async блок кода в очереди, которая в настоящее время заблокирована собственной операцией dispatch_sync? Блокируют ли они или блокирует ли очередь после завершения операции dispatch_sync?GCD - dispatch_async на заблокированной очереди

У меня есть объект, который я создал, который управляет доступом к хранилищу резервных копий (в этом случае SQLite). Он использует одну очередь concurrent GCD, и любые другие объекты, которые хотят получить доступ к информации из магазина, передадут запрос менеджеру вместе с блоком, который будет выполняться асинхронно. Суть того, что происходит это (не фактический код):

- (void) executeRequest:(StoreRequest *)request withCompletionBlock:(void(^)(NSInteger result)block{ 
    dispatch_queue_t currentContext = dispatch_get_current_queue(); 
    dispatch_async(_storeQueue, ^{ 
     NSInteger result = [_store executeRequest:request]; 
     if (block){ 
      dispatch_async(currentContext, ^{ 
       block(result); 
      } 
     } 
    }); 
} 

Реальный код является немного более сложным (я на самом деле очереди и хранить запросы/блоки/контексты выполнять в конце цикла выполнения) , Я также использую dispatch_barrier_async для запросов на запись, чтобы предотвратить одновременное чтение/запись. Все это прекрасно работает, но в некоторых ситуациях мне также необходимо выполнить синхронный запрос в магазине. Теперь этот запрос не нужно выполнять перед любыми операциями в очереди, но мне нужна блокировка очереди запросов до тех пор, пока операция не будет выполнена. Это можно легко сделать:

- (NSInteger) executeRequest:(StoreRequest *)request{ 
    __block NSInteger result = 0; 
    dispatch_sync(_storeQueue, ^{ 
     result = [_store executeRequest:request]; 
    }); 
    return result; 
} 

Мой вопрос заключается в следующем: Что произойдет, если отложенный асинхронная операция помещается перед синхронной операции отправляет блок кода асинхронно очереди, которая в настоящее время заблокирован синхронной отправки. Другими словами, вышеуказанная операция отправит свой запрос в конце очереди _store и ждет. Но вполне возможно (даже вероятно), что перед ними операции включают асинхронные отправления обратно в очередь ожидания (для других операций). Будет ли это блокировать потоки? Поскольку очереди блоков отправляются асинхронно, очередь _store никогда не будет блокирована и, следовательно, закончит, теоретически разрешив продолжить работу в очереди, но я не уверен, что происходит с блоками, которые были асинхронно отправлены или если что-то отправлено блокирующий поток блокирует его. Я бы предположил, что заблокированная очередь будет продолжена, закончить ее запрос, а затем процесс отложенных блоков, но я хочу убедиться.

На самом деле, теперь, когда я все это написал, я уверен, что все будет хорошо, но я все равно отправлю этот вопрос, чтобы убедиться, что я ничего не пропустил.

ответ

1

dispatch_async никогда не блокирует. Это так просто.

+0

Да, я не беспокоился о очереди '_store', так как все его рассылки были асинхронными. Я беспокоился о очереди, с которой она отправлялась, поскольку она была заблокирована во время отправки. В основном, у меня только что запутались в голове, и я начал думать о очередях как о потоках. Иногда я забываю, что очереди - это не потоки, поэтому, конечно, отправленный блок будет просто ждать, пока очередь заблокирует очередь и продолжит, как обычно. Это весь смысл GCD .... возможно, больше кофе поможет. :) –

1

Сама dispatch_async никогда не блокирует. Он добавляет блок в конец очереди и немедленно возвращается.

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

+0

GCD имеет ограничение на 64 потока. См. Http://stackoverflow.com/questions/15150308/workaround-on-the-threads-limit-in-grand-central-dispatch –

Смежные вопросы