Question: Implement a job scheduler which takes in function f and int n and calls f after n seconds.
Since im using Obj C to answer this question, I should probably use dispatch queues instead of selectors or function pointers.
Here's my attempt to implement the answer, but it's not returning a time stamp:
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;
}
What could I be doing wrong?
Also my intended implementation would be able to call jobSch(queue, 10, aBlock) at runtime 0 and jobSch(queue, 3, aBlock) at runtime 2, so that would mean the second call would print before the first.
The problem is that main
is exiting long before your enqueued block is run. And that is because your call to dispatch_group_wait
isn't waiting. And that is because your dispatch group is empty.
In order for a dispatch group and a call to dispatch_group_wait
to be useful, you need to make paired calls to dispatch_group_enter
and dispatch_group_leave
.
You need to call dispatch_group_enter
before you start any async call and you need to call dispatch_group_leave
after the block has finished (aBlock
in this case).
Your code is not setup to make this easy. You would need to make group
a global variable. Then you can call dispatch_group_enter
and dispatch_group_leave
where needed.
Something like this should work:
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;
}
Also note that you never actually make use of queue
inside jobSch
.
You need to change:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, n * NSEC_PER_SEC), dispatch_get_main_queue(), f);
to:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, n * NSEC_PER_SEC), queue, f);