0

Я пытаюсь создать двоичный семафор, используя GCD. У меня есть 2 метода -> Один для запроса ресурса, а другой для освобождения ресурса.Двоичный семафор с использованием 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. 

Проблема возникает, когда я вызываю выпуск дважды. Я вижу, что счет семафора увеличивается до 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? И какое решение здесь? Должен ли я проверить значение перед вызовом выпуска?

ответ

0

Отправка семафора не является двоичным семафором. Он подсчитывает семафор.

dispatch_semaphore_create

синхронизирован подсчет семафор

и отправка семафор не имеет никакой функциональности, чтобы ограничить максимальное количество. Таким образом, поведение такое же, как ожидаемое поведение.

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 

Puteread mutex - это почти то, что вы хотите. Он отлично работает с GCD, но у него нет тайм-аута. Вам нужно реализовать тайм-аут самостоятельно, как this.

+0

Если я хочу использовать НОД, то у меня будет осуществлять проверку на счета КТ? –

+0

Как? Вы не можете получить значение счета Dispatch Semaphore. –

+0

Я не могу получить значение семафора. Но я могу сохранить счет в своем коде. В основном, обертывая инициализацию, запрос и выпуск методов в другом классе и поддерживая счет в классе-оболочке. Мне придется заблокировать методы запроса и выпуска. Вы видите какие-либо проблемы с этим подходом? –

Смежные вопросы