Реализация планировщика заданий с использованием очередей рассылки - PullRequest
0 голосов
/ 21 октября 2018

Вопрос: Реализуйте планировщик заданий, который принимает функции f и int n и вызывает f через n секунд.

Поскольку я использую 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;
}

Что я мог сделать не так?

Также мой намеченныйРеализация сможет вызывать JobSch (очередь, 10, aBlock) во время выполнения 0 и JobSch (очередь, 3, aBlock) во время выполнения 2, так что это будет означать, что второй вызов будет напечатан до первого.

1 Ответ

0 голосов
/ 22 октября 2018

Проблема в том, что main завершается задолго до запуска блока в очереди.И это потому, что ваш звонок на dispatch_group_wait не ждет.И это потому, что ваша группа рассылки пуста.

Чтобы группа рассылки и звонок на dispatch_group_wait были полезны, вам нужно сделать парные звонки на dispatch_group_enter и dispatch_group_leave. * 1008.*

Вам необходимо позвонить dispatch_group_enter перед началом любого асинхронного вызова, и вам нужно позвонить dispatch_group_leave после завершения блока (aBlock в этом случае).

Ваш код не настроенчтобы сделать это легко.Вам нужно будет сделать group глобальной переменной.Тогда вы можете позвонить dispatch_group_enter и dispatch_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);
...