MST

星途 面试题库

面试题:Objective-C多线程编程中如何通过GCD避免线程饥饿问题

在Objective-C使用Grand Central Dispatch (GCD)进行多线程编程时,线程饥饿可能会因为任务优先级设置不合理等原因出现。请详细说明如何通过GCD的特性(如队列优先级管理、任务调度机制等)来有效避免线程饥饿问题,并给出相应代码实现。
13.9万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

避免线程饥饿的方法

  1. 队列优先级管理
    • GCD提供了不同优先级的队列,包括DISPATCH_QUEUE_PRIORITY_HIGHDISPATCH_QUEUE_PRIORITY_DEFAULTDISPATCH_QUEUE_PRIORITY_LOWDISPATCH_QUEUE_PRIORITY_BACKGROUND。通过合理设置任务所在队列的优先级,可以避免高优先级任务持续占用资源导致低优先级任务饥饿。例如,将一些非关键的后台任务放在低优先级队列中,而将用户交互相关的关键任务放在高优先级队列中。
  2. 任务调度机制
    • Dispatch Groups:使用dispatch_group可以将多个任务组合在一起,并在所有任务完成后执行一个完成块。这有助于控制任务的执行顺序,避免某个任务因为一直等待其他任务完成而饥饿。例如,在一组任务中有一个需要依赖其他任务结果的任务,可以使用dispatch_group确保依赖的任务先完成。
    • Dispatch Semaphoresdispatch_semaphore可以用来控制同时执行的任务数量。通过设置信号量的值,可以限制高优先级任务的并发数量,从而给低优先级任务执行的机会。例如,如果有大量高优先级任务不断进入队列,可以通过信号量限制同时执行的高优先级任务数量,让低优先级任务也能有机会获取资源执行。

代码实现

  1. 队列优先级管理示例
dispatch_queue_t highPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t lowPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

// 高优先级任务
dispatch_async(highPriorityQueue, ^{
    NSLog(@"High priority task is running");
    // 模拟任务执行
    sleep(2);
    NSLog(@"High priority task is finished");
});

// 低优先级任务
dispatch_async(lowPriorityQueue, ^{
    NSLog(@"Low priority task is running");
    // 模拟任务执行
    sleep(2);
    NSLog(@"Low priority task is finished");
});
  1. Dispatch Groups示例
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// 任务1
dispatch_group_async(group, queue, ^{
    NSLog(@"Task 1 is running");
    sleep(1);
    NSLog(@"Task 1 is finished");
});

// 任务2
dispatch_group_async(group, queue, ^{
    NSLog(@"Task 2 is running");
    sleep(1);
    NSLog(@"Task 2 is finished");
});

// 所有任务完成后的回调
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"All tasks are finished");
});
  1. Dispatch Semaphores示例
dispatch_semaphore_t semaphore = dispatch_semaphore_create(2); // 允许同时执行2个高优先级任务
dispatch_queue_t highPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t lowPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

// 高优先级任务
for (int i = 0; i < 5; i++) {
    dispatch_async(highPriorityQueue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"High priority task %d is running", i);
        sleep(1);
        NSLog(@"High priority task %d is finished", i);
        dispatch_semaphore_signal(semaphore);
    });
}

// 低优先级任务
dispatch_async(lowPriorityQueue, ^{
    NSLog(@"Low priority task is running");
    sleep(2);
    NSLog(@"Low priority task is finished");
});