iOS多线程GCD - dispatch_group

122 阅读5分钟

演示方案:

  1. 精简的 goup 函数,不带 enter 和 leave
  2. 完成的 group 函数,带 enter 和 leave
  3. 丰富的 group 函数,带 wait 函数
    • 3.1 wait 先于 blocks 任务执行
    • 3.2 wait 后于 blocks 任务执行

1. 精简的 group 函数

- (**void**)group_simple_1 {
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("group_simple_1", DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"-----group_simple_1 begin");
    dispatch_group_async(group, queue, ^{
        sleep(1);
        NSLog(@"\n\tthread = %@, group_simple_1 -01", [NSThread currentThread]);
    });

    dispatch_group_async(group, queue, ^{
        sleep(3);
        NSLog(@"\n\tthread = %@, group_simple_1 -02", [NSThread currentThread]);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"\n\tthread = %@, group_simple_1 -03", [NSThread currentThread]);
    });

    dispatch_group_notify(group, queue, ^{
        NSLog(@"\n\tthread = %@, group_simple_1 notify!", [NSThread currentThread]);
    });
    
    NSLog(@"group_simple_1 end-----");
}
/*
 group_simple_1 运行结果

 小结:
    - 所有block任务和notify任务都在子线程。
    - 当所有异步任务blocks运行完成之后,再运行notify任务通知。

 2022-10-30 12:13:25.051815+0800 iOSMultiThread[25219:1547152] -----group_simple_1 begin
 2022-10-30 12:13:25.051965+0800 iOSMultiThread[25219:1547152] group_simple_1 end-----
 2022-10-30 12:13:25.052054+0800 iOSMultiThread[25219:1547251] 
     thread = <NSThread: 0x600002998900>{number = 5, name = (null)}, group_simple_1 -03
 2022-10-30 12:13:26.052953+0800 iOSMultiThread[25219:1547255] 
     thread = <NSThread: 0x60000299cd80>{number = 6, name = (null)}, group_simple_1 -01
 2022-10-30 12:13:28.054653+0800 iOSMultiThread[25219:1547250] 
     thread = <NSThread: 0x6000029993c0>{number = 7, name = (null)}, group_simple_1 -02
 2022-10-30 12:13:28.055040+0800 iOSMultiThread[25219:1547250] 
     thread = <NSThread: 0x6000029993c0>{number = 7, name = (null)}, group_simple_1 notify!
 */

2. 完成的 group 函数,带 enter 和 leave

- (**void**)group_02 {
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("group_02", DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"-----group_02 begin");

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(1);
            NSLog(@"\n\tthread = %@, group_02 -01", [NSThread currentThread]);

            dispatch_group_leave(group);
        });
    });

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(3);
            NSLog(@"\n\tthread = %@, group_02 -02", [NSThread currentThread]);

            dispatch_group_leave(group);
        });
    });

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"\n\tthread = %@, group_02 -03", [NSThread currentThread]);

            dispatch_group_leave(group);
        });
    });

    dispatch_group_notify(group, queue, ^{
        NSLog(@"\n\tthread = %@, group_02 notify!", [NSThread currentThread]);
    });

    NSLog(@"group_02 end-----");
}
/*
 group_02 运行结果

 小结:
    - 所有block任务和notify任务都在子线程。
    - 当所有异步任务blocks其内部的异步任务运行完成之后,再运行notify任务通知。

 2022-10-30 12:21:08.329613+0800 iOSMultiThread[25469:1555074] -----group_02 begin
 2022-10-30 12:21:08.329731+0800 iOSMultiThread[25469:1555074] group_02 end-----
 2022-10-30 12:21:08.329837+0800 iOSMultiThread[25469:1555193] 
     thread = <NSThread: 0x600001435940>{number = 3, name = (null)}, group_02 -03
 2022-10-30 12:21:09.329834+0800 iOSMultiThread[25469:1555189] 
     thread = <NSThread: 0x600001433cc0>{number = 7, name = (null)}, group_02 -01
 2022-10-30 12:21:11.334358+0800 iOSMultiThread[25469:1555194] 
     thread = <NSThread: 0x6000014430c0>{number = 4, name = (null)}, group_02 -02
 2022-10-30 12:21:11.334764+0800 iOSMultiThread[25469:1555194] 
     thread = <NSThread: 0x6000014430c0>{number = 4, name = (null)}, group_02 notify!
 */

3. 丰富的 group 函数,带 wait 函数

- (**void**)group_wait {
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("group_wait", DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"-----group_wait begin");

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(1);
            NSLog(@"\n\tthread = %@, group_wait -01", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
    });

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(3);
            NSLog(@"\n\tthread = %@, group_wait -02", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
    });

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"\n\tthread = %@, group_wait -03", [NSThread currentThread]);
            dispatch_group_leave(group);
        })
    });

    dispatch_group_notify(group, queue, ^{
        NSLog(@"\n\tthread = %@, group_wait notify01!", [NSThread currentThread]);
    });

    dispatch_group_notify(group, queue, ^{
        NSLog(@"\n\tthread = %@, group_wait notify02!", [NSThread currentThread]);
    });
    
    NSLog(@"group_wait: before wait");

    **long** result = dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
//    long result = dispatch_group_wait(group, 2);

    NSLog(@"group_wait: after wait, result = %ld", result);

    NSLog(@"group_wait end-----");
}
/*
 group_wait 运行结果 timeout: dispatch_time_forever

 2022-10-30 12:35:24.314751+0800 iOSMultiThread[25959:1571424] -----group_wait begin
 2022-10-30 12:35:24.314908+0800 iOSMultiThread[25959:1571424] group_wait: before wait
 2022-10-30 12:35:24.315525+0800 iOSMultiThread[25959:1571538] 
     thread = <NSThread: 0x600001493840>{number = 4, name = (null)}, group_wait -03
 2022-10-30 12:35:25.318248+0800 iOSMultiThread[25959:1571533] 
     thread = <NSThread: 0x6000014d83c0>{number = 6, name = (null)}, group_wait -01
 2022-10-30 12:35:27.316223+0800 iOSMultiThread[25959:1571537] 
     thread = <NSThread: 0x600001482740>{number = 3, name = (null)}, group_wait -02
 2022-10-30 12:35:27.316545+0800 iOSMultiThread[25959:1571424] group_wait: after wait, result = 0

 2022-10-30 12:35:27.316605+0800 iOSMultiThread[25959:1571537] 
     thread = <NSThread: 0x600001482740>{number = 3, name = (null)}, group_wait notify01!
 2022-10-30 12:35:27.316606+0800 iOSMultiThread[25959:1571533] 
     thread = <NSThread: 0x6000014d83c0>{number = 6, name = (null)}, group_wait notify02!

 2022-10-30 12:35:27.316747+0800 iOSMultiThread[25959:1571424] group_wait end-----
 */
/*
 group_wait 运行结果 timeout: 2

 2022-10-30 12:34:42.942999+0800 iOSMultiThread[25928:1570149] -----group_wait begin
 2022-10-30 12:34:42.943165+0800 iOSMultiThread[25928:1570149] group_wait: before wait
 2022-10-30 12:34:42.943292+0800 iOSMultiThread[25928:1570149] group_wait: after wait, result = 49
 2022-10-30 12:34:42.943305+0800 iOSMultiThread[25928:1570301] 
     thread = <NSThread: 0x600000b7c340>{number = 4, name = (null)}, group_wait -03
 2022-10-30 12:34:42.943407+0800 iOSMultiThread[25928:1570149] group_wait end-----

 2022-10-30 12:34:43.943505+0800 iOSMultiThread[25928:1570296] 
     thread = <NSThread: 0x600000b31c40>{number = 7, name = (null)}, group_wait -01
 2022-10-30 12:34:45.944082+0800 iOSMultiThread[25928:1570298] 
     thread = <NSThread: 0x600000b64d40>{number = 6, name = (null)}, group_wait -02

 2022-10-30 12:34:45.944321+0800 iOSMultiThread[25928:1570298] 
     thread = <NSThread: 0x600000b64d40>{number = 6, name = (null)}, group_wait notify01!
 2022-10-30 12:34:45.944336+0800 iOSMultiThread[25928:1570296] 
     thread = <NSThread: 0x600000b31c40>{number = 7, name = (null)}, group_wait notify02!
 */
/*
 group_wait timeout: dispatch_time_forever

 小结:
    - 当有group_wait时,阻塞当前线程但不影响blocks异步任务。
    - group的所有block都完成或者block没有都完成但是已经到了指定的超时时间,就继续往下执行。
    - 当blocks任务都执行完成之后,再异步执行notify通知。可以进行多个notify通知。
 */