Skip to content

Instantly share code, notes, and snippets.

@yanhsiah
Created December 18, 2017 02:53
Show Gist options
  • Save yanhsiah/8f525f5552690e8e4830b3a59e5c0a51 to your computer and use it in GitHub Desktop.
Save yanhsiah/8f525f5552690e8e4830b3a59e5c0a51 to your computer and use it in GitHub Desktop.
mutex lock example for objective-C
- (void)sampleMethod
{
NSOperationQueue *operationQueue = [NSOperationQueue new];
MockService *service = [MockService sharedService];
[operationQueue addOperationWithBlock:^{
NSString *key = @"url_1";
[service runServiceByKey:key];
}];
[operationQueue addOperationWithBlock:^{
NSString *key = @"url_2";
[service runServiceByKey:key];
}];
[operationQueue addOperationWithBlock:^{
NSString *key = @"url_1";
[service runServiceByKey:key];
}];
[operationQueue addOperationWithBlock:^{
NSString *key = @"url_3";
[service runServiceByKey:key];
}];
}
///////////////////////////////////////////////////////////////////
#import <Foundation/Foundation.h>
@interface MockService : NSObject
+ (MockService *)sharedService;
- (void)runServiceByKey:(NSString *)key;
@end
///////////////////////////////////////////////////////////////////
#import "MockService.h"
#import <pthread.h>
pthread_mutex_t mutex;
@interface MockService ()
@property (nonatomic) NSMutableSet *keys;
@end
@implementation MockService
+ (MockService *)sharedService
{
static dispatch_once_t onceToken;
static MockService *instance;
dispatch_once(&onceToken, ^{
instance = [[MockService alloc] init];
instance.keys = [NSMutableSet set];
pthread_mutex_init(&mutex, NULL);
});
return instance;
}
- (void)runServiceByKey:(NSString *)key
{
NSLog(@"%@: %@ <-- try get lock", [NSThread currentThread], key);
if (![self isRepeatedKey:key]) {
NSLog(@"%@: %@ <-- not repeat, run!", [NSThread currentThread], key);
sleep(1);
NSLog(@"%@: %@ -->", [NSThread currentThread], key);
pthread_mutex_lock(&mutex);
[self.keys removeObject:key];
pthread_mutex_unlock(&mutex);
}
else {
NSLog(@"%@: %@ --> repeated, skip", [NSThread currentThread], key);
}
return;
}
- (BOOL)isRepeatedKey:(NSString *)key
{
BOOL isRepeated;
int lock_res = pthread_mutex_lock(&mutex);
if (!lock_res) {
NSLog(@"%@: %@ <-- get lock success", [NSThread currentThread], key);
}
else {
NSLog(@"%@: %@ <-- get lock failure", [NSThread currentThread], key);
}
isRepeated = [self.keys containsObject:key];
if (!isRepeated) {
[self.keys addObject:key];
}
pthread_mutex_unlock(&mutex);
return isRepeated;
}
@end
///////////////////////////////////////////////////////////////////
<NSThread: 0x604000265d40>{number = 4, name = (null)}: url_1 <-- try get lock
<NSThread: 0x60c0002638c0>{number = 3, name = (null)}: url_1 <-- try get lock
<NSThread: 0x600000275140>{number = 6, name = (null)}: url_2 <-- try get lock
<NSThread: 0x600000078b40>{number = 5, name = (null)}: url_3 <-- try get lock
<NSThread: 0x60c0002638c0>{number = 3, name = (null)}: url_1 <-- get lock success
<NSThread: 0x60c0002638c0>{number = 3, name = (null)}: url_1 <-- not repeat, run!
<NSThread: 0x604000265d40>{number = 4, name = (null)}: url_1 <-- get lock success
<NSThread: 0x600000275140>{number = 6, name = (null)}: url_2 <-- get lock success
<NSThread: 0x604000265d40>{number = 4, name = (null)}: url_1 --> repeated, skip
<NSThread: 0x600000275140>{number = 6, name = (null)}: url_2 <-- not repeat, run!
<NSThread: 0x600000078b40>{number = 5, name = (null)}: url_3 <-- get lock success
<NSThread: 0x600000078b40>{number = 5, name = (null)}: url_3 <-- not repeat, run!
<NSThread: 0x60c0002638c0>{number = 3, name = (null)}: url_1 -->
<NSThread: 0x600000275140>{number = 6, name = (null)}: url_2 -->
<NSThread: 0x600000078b40>{number = 5, name = (null)}: url_3 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment