gpt4 book ai didi

ios - 在 iOS 中使用 GCD 实现临界区

转载 作者:行者123 更新时间:2023-11-29 10:43:45 26 4
gpt4 key购买 nike

我有一个非常繁重的任务要执行,我不想阻塞主线程。所以我为它启动了一个单独的并发队列。所述任务可以有 4 个实例。

-(dispatch_queue_t)getConcurrentQueue
{
if(concurrentQueue == nil)
{
concurrentQueue = dispatch_queue_create("com.myself.HeavyTask", DISPATCH_QUEUE_CONCURRENT);
}
return concurrentQueue;
}

现在开始我的重任——

-(void)beginTask
{
//.....
//.....
__weak typeof(self) weakSelf = self;
dispatch_queue_t queue = [self getConcurrentQueue];
dispatch_async(queue, ^{
[weakSelf heavyTask];
});
}

现在 heavyTask 方法是这样的——

-(void)heavyTask
{
//...
dispatch_sync(dispatch_get_current_queue(), ^{
// Initialising code for heavy task
// This is the critical section. Only one of the 4 concurrent threads can enter this at a time
}
//....

while(condition)
{
// Perform meat of the task
}

//...
dispatch_sync(dispatch_get_current_queue(), ^{
// Teardown code. Freeing memory etc.
// This is also a critical section.
}
//...
}

初始化代码和拆卸代码使用了一些非线程安全的第 3 方 C 方法。所以让它们线程安全不是问题的范围。

现在我已经将“初始化代码”“拆卸代码”放在-

dispatch_sync(dispatch_get_current_queue(), ^{
}

我的代码崩溃了,我收到错误消息,指出关键部分代码周围的线程锁定不足。

我读到 dispatch_get_current_queue() 不安全,所以我将其替换为 concurrentQueue。我还尝试用 dispatch_get_main_queue() 替换。代码仍然崩溃,提示线程锁定不足。

我知道我对使用 GCD 实现临界区的理解有问题。

谁能清楚地告诉我如何让我的代码在这里正常工作?

附带问题 -- 我可以在这里使用 @synchronized { } block 吗??

最佳答案

您的代码有很多错误,包括不遵守命名约定。

所以基本上,如果您想同时彼此执行相同的任务,请使用全局并发队列来执行这些任务。

如果你想从这些任务中(或从其他地方)并发访问共享资源,定义一个专用队列,比如“sync_queue”,你可以在其中专门访问这些资源。这个“sync_queue”执行你的“关键部分”。

“sync_queue”可以是串行的或并发的。

如果您使用串行队列,请使用 dispatch_async(sync_queue, block) 进行写入访问,并使用 dispatch_sync(sync_queue, block) < em>对共享资源的读取权限。

如果您使用并发队列,请使用 dispatch_barrier_async(sync_queue, block) 进行写访问,并使用 dispatch_barrier_sync(sync_queue, block) < em>对共享资源的读取权限。

例子:

// Read access using a serial sync_queue:
...
__block int counter;
dispatch_sync(sync_queue, ^{
counter = _counter;
});


// Write access using a serial sync_queue:
...
dispatch_async(sync_queue, ^{
_counter = counter;
});



// Read access using a concurrent sync_queue:
...
__block int counter;
dispatch_barrier_sync(sync_queue, ^{
counter = _counter;
});


// Write access using a concurrent sync_queue:
...
dispatch_barrier_async(sync_queue, ^{
_counter = counter;
});

“繁重任务”的示例:

-(void)heavyTask
{
dispatch_barrier_async(sync_queue, ^{
// Initialize heavy task
...

// Continue with the task:
dispatch_async(dispatch_get_global_queue(0,0), ^{
BOOL condition = YES; // condition must be local to the block (it's not a shared resource!)
while(condition)
{
// Perform meat of the task
condition = ...;
}

dispatch_barrier_async(sync_queue, ^{
// Teardown code. Freeing memory etc.
// This is also a critical section.
...
}
});
}
}

关于ios - 在 iOS 中使用 GCD 实现临界区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23211659/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com