我对使用dispatch_after
和dispatch_semaphore_t
一起执行某些任务并在每个线程之间等待一段时间感到好奇。
我使用以下代码:
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_after(time, queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"blk01");
dispatch_semaphore_signal(semaphore);
});
dispatch_after(time, queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"blk02");
dispatch_semaphore_signal(semaphore);
});
dispatch_after(time, queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"blk03");
dispatch_semaphore_signal(semaphore);
});
我在3秒后执行线程,而不是预期的延迟。
我做错了什么?有没有其他方法在dispatch_semaphore_t中执行线程,每个线程执行之间有延迟时间?
答案 0 :(得分:4)
如果要串行(不同时)执行三个块,并且想要在块之间暂停,则比使用信号量更简单。最简单的方法是创建一个串行队列,并在每个块的开头或结尾放置sleep
(或usleep
):
dispatch_queue_t queue = dispatch_queue_create("my queue", 0);
dispatch_async(queue, ^{
sleep(3);
NSLog(@"blk01");
});
dispatch_async(queue, ^{
sleep(3);
NSLog(@"blk02");
});
dispatch_async(queue, ^{
sleep(3);
NSLog(@"blk03");
});
dispatch_release(queue);
将sleep
放入块中非常简单,但会占用一个线程。这可能无关紧要,除非你创造了很多队列并且在许多队列中睡觉。
如果您告诉我们您认为自己需要信号量的原因,或许我们可以为您提供更好的替代方案或建议如何正确使用它。
答案 1 :(得分:3)
您的代码不要求每次调用之间有3秒的延迟。它安排了3个块,全部在同一时间,所有3个块都采用信号量和日志。
您需要调整用于调度每个后续块的时间,或者您需要在之前的每个调用中安排后续dispatch_after()
个呼叫。前者可能更简单,并且可以让您获得更精确的计时。如果你选择后者,请务必在每个区块中重新计算time
,因为这是指绝对时间,而不是相对持续时间。