使用调度队列实施作业计划程序

时间:2018-10-21 18:51:05

标签: objective-c grand-central-dispatch dispatch-async

问题:实现一个作业调度程序,该程序接受函数f和int n,并在n秒后调用f。

由于我使用Obj C回答了这个问题,所以我应该使用分派队列而不是选择器或函数指针。

这是我尝试实现答案的尝试,但没有返回时间戳:

void jobSch(dispatch_queue_t queue, int64_t n, dispatch_block_t f)
{
    NSLog(@"%d\n", n);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, n * NSEC_PER_SEC), dispatch_get_main_queue(), f);
}

void (^aBlock)(void) = ^(){
    NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSLog(@"%@",[dateFormatter stringFromDate:[NSDate date]]);
};

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_async(group, queue, ^{
            jobSch(queue, 3, aBlock);
        });
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    }
    return 0;
}

我可能做错了什么?

我的预期实现也将能够在运行时0调用jobSch(queue,10,aBlock),在运行时2调用jobSch(queue,3,aBlock),这意味着第二个调用将在第一个调用之前打印。 / p>

1 个答案:

答案 0 :(得分:2)

问题在于main在您的排队块运行之前很久就退出了。那是因为您对dispatch_group_wait的呼叫没有等待。那是因为您的调度组为空。

为了使调度组和对dispatch_group_wait的调用有用,您需要对dispatch_group_enterdispatch_group_leave进行成对调用。

您需要在开始任何异步调用之前调用dispatch_group_enter,并且在块完成后需要调用dispatch_group_leave(在这种情况下为aBlock)。

未设置您的代码来简化此操作。您需要将group设置为全局变量。然后,您可以在需要时呼叫dispatch_group_enterdispatch_group_leave

类似的事情应该起作用:

dispatch_group_t group;

void jobSch(dispatch_queue_t queue, int64_t n, dispatch_block_t f)
{
    NSLog(@"%d\n", n);
    dispatch_group_enter(group);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, n * NSEC_PER_SEC), queue, f);
}

void (^aBlock)(void) = ^(){
    NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSLog(@"%@",[dateFormatter stringFromDate:[NSDate date]]);
    dispatch_group_leave(group);
};

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        group = dispatch_group_create();

        // no need for dispatch_group_async here
        jobSch(queue, 10, aBlock);
        jobSch(queue, 3, aBlock);

        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    }
    return 0;
}

还要注意,您从未真正使用过queue内的jobSch

您需要更改:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, n * NSEC_PER_SEC), dispatch_get_main_queue(), f);

收件人:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, n * NSEC_PER_SEC), queue, f);