Objective c 使用GCD的二进制信号量

Objective c 使用GCD的二进制信号量,objective-c,xcode,macos,synchronization,grand-central-dispatch,Objective C,Xcode,Macos,Synchronization,Grand Central Dispatch,我正在尝试使用GCD创建一个二进制信号量。我有两种方法->一种用于请求资源,另一种用于释放资源 一切正常,直到我打电话请求时,按顺序释放 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 resourc

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

一切正常,直到我打电话请求时,按顺序释放

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.
当我两次调用release时,问题出现了。我看到信号量计数增加到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之前是否应该检查该值?

调度信号量不是二进制信号量。这是计数信号灯

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

同步计数信号量

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

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 mutex几乎就是您想要的。它与GCD配合使用效果很好,但没有超时。您需要像这样实现超时


如果我想使用GCD,我必须执行计数rt检查?如何执行?您无法获取分派信号量的计数值。我无法获取信号量的值。但是我可以在我的代码中保留计数。基本上是通过在另一个类中包装初始化、请求和释放方法,并在包装类中维护计数。我必须锁定请求和释放方法。你认为这种方法有什么问题吗?它是可行的。但是为什么不使用串行调度队列呢?我建议你问一个关于你真正想做什么的新问题。