2015-05-27 4 views
0

С учетом следующего кода, является ли звонок @synchronized не обязательным?Должен ли я обернуть dispatch_group_leave в блоке @synchronized?

Я предполагаю, что dispatch_group_enter/leave является атомарным, но здесь не указано как потокобезопасное здесь https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/dispatch_group_leave.3.html, и я внезапно волнуюсь, что все это время я возился.

// Imagine this is on its own queue already (possibly main, possibly not) 
dispatch_group_t group = dispatch_group_create(); 
for(x in array){ 
    dispatch_group_enter(group); 
    [x doSomethingAsync:^{ 
    // imagine x is part of a library which sometimes runs blocks on 
    // a different queue. 
    // surely dispatch_group_leave has its own internal synchronization? 
    @synchronized(group){ 
     dispatch_group_leave(group); 
    } 
    }] 
} 
dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

ответ

1

При вызове dispatch_group_enter и dispatch_group_leave дополнительной дополнительной синхронизации не требуется. GCD сам по себе обеспечивает средства параллелизма и потоков. Если бы требовалась дополнительная синхронизация или барьеры, я ожидал, что она будет вызываться явно в документах, так же как требование для dispatch_once_t s для вызова глобального/статического хранилища. Иными словами, GCD - это библиотека потоков, поэтому ожидается, что, если не указано иное, ожидается, что вызовы обеспечат безопасность потоков друг относительно друга.

Это ожидание основано на большом личном опыте и на Грэге Паркере, делающем a similar statement on a mailing list некоторое время назад.

+0

Да, я так много думал, как вы сказали, было бы глупо иметь поточную библиотеку с потоками. – Soup

+0

Как насчет dispatch_group_create? –

+0

Должно быть безопасным. – ipmcc

0

Поскольку вы не создаете темы, не беспокойтесь.

В вашем примере dispatch_group_leave(group) вызывается в той же теме.

+0

На самом деле я думал, что у меня был блок, вызванный другим потоком (по умолчанию обработчики завершения AFNetworking запускаются в основной очереди, а мой код работает в собственной очереди). Я обновил вопрос, чтобы быть немного интереснее? – Soup

+0

Я думаю, что даже если вы 'doSomethingAsync' в другом потоке, блок обратного вызова вызывается в основном потоке. – user623396

+0

Вы можете указать другой поток, если хотите/нужно, поэтому не исключено, что это может произойти, и это заставило меня задуматься, нужен ли там @synchronized. – Soup

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