使用 GCD 的二进制信号量
Binary Semaphore using GCD
我正在尝试使用 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.
调用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 之前检查该值吗?
调度信号量不是二进制信号量。它正在计数信号量。
synchronized counting semaphore
并且 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 mutex 几乎就是你想要的。它适用于 GCD,但没有超时。您需要自己实现超时,例如 this.
我正在尝试使用 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.
调用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 之前检查该值吗?
调度信号量不是二进制信号量。它正在计数信号量。
synchronized counting semaphore
并且 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 mutex 几乎就是你想要的。它适用于 GCD,但没有超时。您需要自己实现超时,例如 this.