使用dispatch_sync作为互斥锁 [英] using dispatch_sync as a mutex lock

查看:98
本文介绍了使用dispatch_sync作为互斥锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我需要做的。
我希望dispatch_sync是使用GCD实现它的最佳方式

Here is what I need to do. I hope dispatch_sync would be the best way to do it using GCD

我有一段临界区代码放在appdelegate的applicationDidBecomeActive回调中..

I have a certain piece of critical section code that is placed in the applicationDidBecomeActive callback in Appdelegate..

我在dispatch_sync调用中包装该方法,因此无论调用applicationDidBecomeActive多少次都只调用它一次

I am wrapping up that method inside a dispatch_sync call so that it gets called only once no matter how many times applicationDidBecomeActive is called

- (void)applicationDidBecomeActive:(UIApplication *)application{    
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    
    NSLog(@"Thread created");
    //crtical code
    [self runCriticalSection];        
});}

这是使用dispatch_sync进行此操作的正确方法吗?

Is this the right way for doing it using dispatch_sync?

推荐答案

dispatch_sync()在块完成之前不会返回,这意味着
applicationDidBecomeActive 直到<$ c $才会返回C> runCriticalSectio n 已完成
执行。

dispatch_sync() does not return until the block has finished, which means that applicationDidBecomeActive does not return until runCriticalSection has finished execution.

这可能不是您想要的,因此您必须使用 dispatch_async()(已经在另一个答案中说明了
)。

This is probably not what you want, therefore you have to use dispatch_async() (as already stated in the other answer).

但是你不想要另一个 runCriticalSection 如果前一个仍在运行,则启动
。这可以通过计数信号量
(这也是GCD的一个功能)来实现:

But you don't want another runCriticalSection to start if the previous one is still running. This can be achieved with a "counting semaphore" (which are also a feature of GCD):

static dispatch_semaphore_t sema; // The semaphore
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // Initialize with count=1 (this is executed only once):
    sema = dispatch_semaphore_create(1);
});

// Try to decrement the semaphore. This succeeds if the count is still 1
// (meaning that runCriticalSection is not executing), and fails if the 
// current count is 0 (meaning that runCriticalSection is executing):
if (dispatch_semaphore_wait(sema, DISPATCH_TIME_NOW) == 0) {
    // Success, semaphore count is now 0.
    // Start asynchronous operation.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //critical code
        [self runCriticalSection];
        // Increment the semaphore count (from 0 to 1), so that the next call
        // to applicationDidBecomeActive will start a new operation:
        dispatch_semaphore_signal(sema);
    });
}

这篇关于使用dispatch_sync作为互斥锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆