二进制信号量使用GCD

时间:2015-07-03 07:02:35

标签: objective-c xcode macos synchronization grand-central-dispatch

我正在尝试使用GCD创建二进制信号量。我有2种方法 - >一个用于请求资源,另一个用于释放资源。

一切正常,直到我打电话请求,按顺序发布。

Call 1 -> Request // I get resource. Semaphore value changes to 0
Call 2 -> Release // resource is released. Semaphore value changes to 1
Call 3 -> Request // I get resource. Semaphore value changes to 0
Call 4 -> Request // Resource is denied, which is expected.

当我两次拨打电话时出现问题。我看到信号量计数增加到2,即使它是二进制信号量。

Call 1 -> Request // I get resource. Semaphore value changes to 0
Call 2 -> Release // resource is released. Semaphore value changes to 1
Call 3 -> Release // Semaphore value changes to 2
Call 4 -> Request // I get resource. Semaphore value changes to 1
Call 5 -> Request // resource is allocated twice, which is not expected. Semaphore value changes to 0

这是我使用的代码。

#define WAIT_INTERVAL 2

@implementation GCDSemaphore
{
    dispatch_semaphore_t resourceAccess;
    dispatch_time_t milestone;
}

+ (GCDSemaphore *)sharedInstance
{
    static dispatch_once_t onceToken;
    static GCDSemaphore *instance = nil;
    dispatch_once(&onceToken, ^{
        instance = [[GCDSemaphore alloc] init];

    });
    return instance;
}

-(id)init {
    if(self = [super init]) {
        resourceAccess = dispatch_semaphore_create(0);
        dispatch_semaphore_signal(resourceAccess);
        milestone = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(WAIT_INTERVAL * NSEC_PER_SEC));
    }
    return self;
}

- (BOOL) requestResource
{
    long ret = dispatch_semaphore_wait(resourceAccess, milestone);
    if(ret == 0)
    {
        return YES;
    }
    return NO;
}

- (BOOL) releaseResource
{
    long ret = dispatch_semaphore_signal(resourceAccess);
    return YES;
}

知道为什么信号量值超过1?这里有什么解决方案?我应该在调用release之前检查该值吗?

1 个答案:

答案 0 :(得分:0)

Dispatch信号量不是二进制信号量。它正在计算信号量。

dispatch_semaphore_create

  

同步计数信号量

Dispatch信号量没有任何限制最大计数的功能。因此行为与预期行为相同。

Call 1 -> Request // I get resource. Semaphore value changes to 0
Call 2 -> Release // resource is released. Semaphore value changes to 1
Call 3 -> Release // Semaphore value changes to 2

Pthread互斥几乎就是你想要的。它适用于GCD但它没有超时。您需要自己实现超时,如this