Como esperar que as filas do GCD sejam suspensas antes de realizar uma tarefa

Recentemente, enfrentei o seguinte problema: controlamos o acesso a alguns recursos (por exemplo, banco de dados / sistema de arquivos) canalizando todo o acesso a esses recursos por meio de uma fila serial. Dessa forma, podemos garantir que nenhum dois threads acessem o banco de dados simultaneamente por acidente. No entanto, agora precisamos pausar todo o acesso ao banco de dados enquanto trocamos o arquivo do banco de dados abaixo. Como ter certeza de que nenhuma tarefa está acessando o banco de dados no momento antes de iniciar a troca de arquivos e garantir que nada aconteça durante a operação?

A ideia que tínhamos era para dispatch_suspenda fila de dentro de uma tarefa enviada para essa mesma fila e retomar a fila somente depois que a troca de arquivos for concluída. Você pode combinar isso com dispatch_groupesperar a tarefa terminar antes de continuar:

dispatch_queue_t queue1 = dispatch_queue_create("com.mekentosj.queue1", 0);
dispatch_queue_t queue2 = dispatch_queue_create("com.mekentosj.queue2", 0);
dispatch_group_t group = dispatch_group_create();

dispatch_async
(queue1, ^{
NSLog(@"Job 1 on queue 1...");
sleep
(1);
NSLog(@"Done 1");
});

dispatch_async
(queue2, ^{
NSLog(@"Job 1 on queue 2...");
sleep
(1);
NSLog(@"Done 2");
});

dispatch_group_async
(group, queue1, ^{
NSLog(@"Suspending queue 1");
dispatch_suspend
(queue1);
});
dispatch_group_async
(group, queue2, ^{
NSLog(@"Suspending queue 2");
dispatch_suspend
(queue2);
});

dispatch_group_wait
(group, DISPATCH_TIME_FOREVER);
NSLog(@"Finished waiting for queues to stop, doing something...");
dispatch_async
(queue1, ^{
NSLog(@"Job 2 queue 1");
});
dispatch_async
(queue2, ^{
NSLog(@"Job 2 queue 2");
});
NSLog(@"This will happen before the two logs above");

dispatch_resume
(queue1);
dispatch_resume
(queue2);

sleep
(1); // just let the background jobs finish