iOS 中的操作同步挑战

Operation synchronisation challenge in iOS

我有 3 个操作:ABC

我会用调度组和信号量来解决:

public var dgLoadMain = dispatch_group_create()
public var semaLoadMain = dispatch_semaphore_create(1)

AB 看起来像这样:

dispatch_group_enter(dgLoadMain)
dispatch_semaphore_wait(semaLoadMain, DISPATCH_TIME_FOREVER)
dispatch_semaphore_signal(semaLoadMain) //maybe odd, but right after wait, it signals, it just check wether C is in critical section, if not, release semaphore, and let other B or A continue too
//..
dispatch_group_leave(dgLoadMain)

C 看起来像这样:

dispatch_group_wait(dgLoadMain, DISPATCH_TIME_FOREVER)
dispatch_semaphore_wait(semaLoadMain, DISPATCH_TIME_FOREVER)
//..
dispatch_semaphore_signal(semaLoadMain)

你觉得可以吗?

您的解决方案可能有效,但对其正确性的推理很痛苦。我想出了我认为更清洁的解决方案。它使用 2 个信号量。它基本上将任务 A 和任务 B 结合起来,并将它们视为一个任务。然后它使用超时 属性 检查任务 A 或任务 B 之前是否完成并相应地向第一个信号量发出信号。这是代码:

let semaphore = dispatch_semaphore_create(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
let ABSema = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
    print("A")
    if !Bool(dispatch_semaphore_wait(ABSema, DISPATCH_TIME_NOW))
    {
        dispatch_semaphore_signal(ABSema)
    }
    else
    {
        dispatch_semaphore_signal(semaphore)
    }

})
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
    print("B")
    if !Bool(dispatch_semaphore_wait(ABSema, DISPATCH_TIME_NOW))
    {
        dispatch_semaphore_signal(ABSema)
    }
    else
    {
        dispatch_semaphore_signal(semaphore)
    }
})


dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
    print("C")
    dispatch_semaphore_signal(semaphore)
})

dispatch_barrier_async 更复杂。看看这段代码。它是 Objective-C,但同样的概念在 Swift 上绝对适用。

#import <Foundation/Foundation.h>

void A()
{
    NSLog(@"A begin");
    sleep(1);
    NSLog(@"A end");
}

void B()
{
    NSLog(@"B begin");
    sleep(1);
    NSLog(@"B end");
}

void C()
{
    NSLog(@"C begin");
    sleep(1);
    NSLog(@"C end");
}

int main()
{
    dispatch_queue_t q = dispatch_queue_create("ABC", DISPATCH_QUEUE_CONCURRENT);

    dispatch_queue_t qA = dispatch_queue_create("A", DISPATCH_QUEUE_SERIAL);
    dispatch_set_target_queue(qA, q);

    dispatch_queue_t qB = dispatch_queue_create("B", DISPATCH_QUEUE_SERIAL);
    dispatch_set_target_queue(qB, q);

    dispatch_barrier_async(q, ^{C();});
    dispatch_async(qA, ^{A();});
    dispatch_async(qA, ^{A();});
    dispatch_async(qB, ^{B();});
    dispatch_barrier_async(q, ^{C();});
    dispatch_async(qB, ^{B();});
    dispatch_barrier_async(q, ^{C();});
    dispatch_async(qA, ^{A();});

    dispatch_main();
    return 0;
}

结果。

C begin
C end
A begin
B begin
A end
B end
B begin
A begin
B end
A end
A begin
A end
C begin
C end
C begin
C end