美文网首页
iOS:常见的锁

iOS:常见的锁

作者: 春暖花已开 | 来源:发表于2020-08-11 10:38 被阅读0次

加锁是为了防止多条线程同时访问同一块内存,也就是为了线程同步。实现线程同步不仅仅只有加锁的方式,也可以通过 同步串行 来实现。

BaseOperation.h
#import <Foundation/Foundation.h>

@interface BaseOperation : NSObject

///测试
- (void)test;

- (void)otherTest;

///存钱
- (void)saveMoeney;
///取钱
- (void)withdrawMoeney;

@end


@interface SemphoreOperation : BaseOperation
@end


@interface SynchronizedOperation : BaseOperation
@end


@interface NSConditionLockOperation : BaseOperation
@end

///生产者-消费者模式
@interface NSConditionOperation : BaseOperation
@end


@interface NSLockOperation : BaseOperation
@end


@interface os_unfair_lockOperation : BaseOperation
@end


@interface SerialQueueOperation : BaseOperation
@end

///生产者-消费者模式
@interface MutexOperation : BaseOperation
@end
BaseOperation.m
#import "BaseOperation.h"

#pragma mark - BaseOperation
@interface BaseOperation ()

@property (nonatomic, assign) NSInteger money;

@end

@implementation BaseOperation

- (void)test {
    
    self.money = 100;
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 5; i++) {
            [self saveMoeney];
        }
    });
    
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 5; i++) {
            [self withdrawMoeney];
        }
    });
}

- (void)otherTest { }

- (void)saveMoeney {
    
    NSInteger oldMoney = self.money;
    sleep(.2);
    oldMoney += 50;
    self.money = oldMoney;
    NSLog(@"存钱50,还剩%ld元 - %@", oldMoney, [NSThread currentThread]);
}

- (void)withdrawMoeney {
    
    NSInteger old = self.money;
    sleep(.2);
    old -= 50;
    self.money = old;
    NSLog(@"取钱50后: %ld元 -- %@", self.money, [NSThread currentThread]);
}

@end


#pragma mark - NSConditionOperation
@interface NSConditionOperation ()

@property (nonatomic, strong) NSCondition *condition;
@property (strong, nonatomic) NSMutableArray *dataList;

@end

@implementation NSConditionOperation

- (instancetype)init {
    if (self = [super init]) {
        self.condition = [[NSCondition alloc] init];
        self.dataList = [NSMutableArray array];
    }
    return self;
}

- (void)otherTest {
    [[[NSThread alloc] initWithTarget:self selector:@selector(__consume) object:nil] start];
    [[[NSThread alloc] initWithTarget:self selector:@selector(__produce) object:nil] start];
}

///消耗
- (void)__consume {
    
    //加锁
    [self.condition lock];
    
    NSLog(@"__consume - begin");
    if (self.dataList.count == 0) {
        //等待: 阻塞当前线程,直到条件发出信号为止
        [self.condition wait];
    }
    
    [self.dataList removeLastObject];
    NSLog(@"%s %@", __func__, [NSThread currentThread]);
    
    //解锁
    [self.condition unlock];
}

///生产
- (void)__produce {
    
    [self.condition lock];
    
    sleep(1);
    [self.dataList addObject:@"Lynn Zhang"];
    
    NSLog(@"%s %@", __func__, [NSThread currentThread]);
    
    //唤醒等待的线程
    [self.condition signal];
    
    sleep(2);
    [self.condition unlock];
}

@end


#pragma mark - NSConditionLock
@interface NSConditionLockOperation ()

@property (nonatomic, strong) NSConditionLock *conditionLock;

@end

@implementation NSConditionLockOperation

- (instancetype)init {
    if (self = [super init]) {
        //初始化一个NSConditionLock对象
        self.conditionLock = [[NSConditionLock alloc] initWithCondition:1];
    }
    return self;
}

- (void)otherTest {
    [[[NSThread alloc] initWithTarget:self selector:@selector(__one) object:nil] start];
    [[[NSThread alloc] initWithTarget:self selector:@selector(__two) object:nil] start];
    [[[NSThread alloc] initWithTarget:self selector:@selector(__three) object:nil] start];
}

- (void)__one {
    [self.conditionLock lockWhenCondition:3];
    
    NSLog(@"%s, %@", __func__, [NSThread currentThread]);
    sleep(1);
    
    //解锁后,重置锁的条件
    [self.conditionLock unlockWithCondition:2];
}

- (void)__two {
    [self.conditionLock lockWhenCondition:1];
    
    NSLog(@"%s, %@", __func__, [NSThread currentThread]);
    sleep(1);
    
    [self.conditionLock unlockWithCondition:3];
}

- (void)__three {
    //满足条件时加锁
    [self.conditionLock lockWhenCondition:2];
    
    NSLog(@"%s, %@", __func__, [NSThread currentThread]);
    sleep(1);
    
    [self.conditionLock unlock];
}

@end


#pragma mark - dispatch_semaphore_t
@interface SemphoreOperation ()

@property (nonatomic, strong) dispatch_semaphore_t semaphore_t;

@end

@implementation SemphoreOperation

- (instancetype)init {
    if (self = [super init]) {
        self.semaphore_t = dispatch_semaphore_create(1);
    }
    return self;
}

- (void)saveMoeney {
    
    dispatch_semaphore_wait(self.semaphore_t, DISPATCH_TIME_FOREVER);
    [super saveMoeney];
    dispatch_semaphore_signal(self.semaphore_t);
}

- (void)withdrawMoeney {
    dispatch_semaphore_wait(self.semaphore_t, DISPATCH_TIME_FOREVER);
    [super withdrawMoeney];
    dispatch_semaphore_signal(self.semaphore_t);
}

@end


#pragma mark - synchronized
@implementation SynchronizedOperation

- (void)saveMoeney {
    @synchronized (self) {
        [super saveMoeney];
    }
}

- (void)withdrawMoeney {
    @synchronized (self) {
        [super withdrawMoeney];
    }
}

@end



#pragma mark - NSLockOperation
@interface NSLockOperation ()

@property (nonatomic, strong) NSLock *lock;

@end

@implementation NSLockOperation

- (instancetype)init {
    if (self = [super init]) {
        self.lock = [[NSLock alloc] init];
    }
    return self;
}

- (void)saveMoeney {
    
    [self.lock lock];
    [super saveMoeney];
    [self.lock unlock];
}

- (void)withdrawMoeney {
    
    [self.lock lock];
    [super withdrawMoeney];
    [self.lock unlock];
}

@end


#pragma mark - os_unfair_lockOperation

#import <os/lock.h>

@interface os_unfair_lockOperation ()

@property (nonatomic, assign) os_unfair_lock lock;

@end

@implementation os_unfair_lockOperation

- (instancetype)init {
    if (self = [super init]) {
        self.lock = OS_UNFAIR_LOCK_INIT;
    }
    return self;
}

- (void)saveMoeney {
    
    os_unfair_lock_lock(&_lock);
    [super saveMoeney];
    os_unfair_lock_unlock(&_lock);
}

- (void)withdrawMoeney {
    
    os_unfair_lock_lock(&_lock);
    [super withdrawMoeney];
    os_unfair_lock_unlock(&_lock);
}

@end


#pragma mark - SerialQueueOperation

@interface SerialQueueOperation ()

@property (strong, nonatomic) dispatch_queue_t serialQueue;

@end

@implementation SerialQueueOperation

- (instancetype)init {
    if (self = [super init]) {
        self.serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    }
    return self;
}

- (void)saveMoeney {
    dispatch_sync(self.serialQueue, ^{
        [super saveMoeney];
    });
}

- (void)withdrawMoeney {
    dispatch_sync(self.serialQueue, ^{
        [super withdrawMoeney];
    });
}

@end


#pragma mark - MutexOperation

#import <pthread.h>

@interface MutexOperation()
@property (assign, nonatomic) pthread_mutex_t mutex;
@property (assign, nonatomic) pthread_cond_t cond;
@property (strong, nonatomic) NSMutableArray *data;
@end

@implementation MutexOperation

- (instancetype)init {
    if (self = [super init]) {
        // 初始化属性
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
        // 初始化锁
        pthread_mutex_init(&_mutex, &attr);
        // 销毁属性
        pthread_mutexattr_destroy(&attr);
        
        // 初始化条件
        pthread_cond_init(&_cond, NULL);
        
        self.data = [NSMutableArray array];
    }
    return self;
}

- (void)otherTest {
    [[[NSThread alloc] initWithTarget:self selector:@selector(__consume) object:nil] start];
    [[[NSThread alloc] initWithTarget:self selector:@selector(__produce) object:nil] start];
}

//消费
- (void)__consume {
    
    pthread_mutex_lock(&_mutex);
    NSLog(@"__consume - begin");
    
    if (self.data.count == 0) {
        // 等待
        pthread_cond_wait(&_cond, &_mutex);
    }
    
    [self.data removeLastObject];
    NSLog(@"删除了元素");
    
    pthread_mutex_unlock(&_mutex);
}

//生产
- (void)__produce {
    
    pthread_mutex_lock(&_mutex);
    
    sleep(1);
    
    [self.data addObject:@"Test"];
    NSLog(@"添加了元素");
    
    // 信号
    pthread_cond_signal(&_cond);
    // 广播
//    pthread_cond_broadcast(&_cond);
    
    pthread_mutex_unlock(&_mutex);
}

- (void)dealloc {
    pthread_mutex_destroy(&_mutex);
    pthread_cond_destroy(&_cond);
}

@end

相关文章

  • iOS 中常见的几种锁-代码示例

    iOS 中常见的几种锁-代码示例 iOS 中常见的几种锁-代码示例

  • OC--各种线程锁

    参考:正确使用多线程同步锁@synchronized()iOS中的锁iOS多线程安全详解iOS 常见知识点(三):...

  • iOS 锁

    iOS Lock(锁) 主要介绍常见的锁,以及synchronized、NSLock、递归锁、条件锁的底层分析 借...

  • iOS常见锁对象

    iOS常见锁对象: 1.互斥锁NSLock NSLock* lock = [[NSLock alloc] init...

  • iOS:常见的锁

    加锁是为了防止多条线程同时访问同一块内存,也就是为了线程同步。实现线程同步不仅仅只有加锁的方式,也可以通过 同步串...

  • iOS中的锁

    锁是一种同步机制,用于多线程环境中对资源访问的限制iOS中常见锁的性能对比图(摘自:ibireme): iOS锁的...

  • Lock

    iOS中以NS开头常见的锁的有NSCondition、NSConditionLock、NSLock、NSRecur...

  • iOS中常见锁

    pthread_mutex POSIX threads(简称Pthreads)定义了一套跨平台的多线程常用API,...

  • iOS中常见的锁

    锁一般用于在多线程中,保证在一段时期内这段代码只能被某一个线程所访问,从而保证线程同步。在iOS中,常用的锁大致有...

  • iOS中的常见锁

    @synchronized 日常开发中常常需要使用锁,可能大多数是使用OC封装的@synchronized,使用起...

网友评论

      本文标题:iOS:常见的锁

      本文链接:https://www.haomeiwen.com/subject/fxpedktx.html