1

我对使用dispatch_afterdispatch_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 中执行线程,每个线程执行之间有延迟时间?

4

2 回答 2

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你的块非常简单,但会占用一个线程。这可能无关紧要,除非您创建了很多队列并在其中的许多队列上睡觉。

如果您告诉我们您认为需要信号量的原因,也许我们可以为您提供更好的替代方案或如何正确使用它的建议。

于 2012-09-07T03:46:52.210 回答
3

您的代码没有要求每次调用之间有 3 秒的延迟。它同时调度 3 个块,所有 3 个块都接收信号量和日志。

您需要调整用于调度每个后续块的时间,或者您需要dispatch_after()在每个先前调用中安排后续调用。前者可能更简单,并且会让您获得更精确的计时。如果您使用后者,请务必time在每个块中重新计算,因为这是指绝对时间,而不是相对持续时间。

于 2012-09-07T03:05:55.767 回答