美文网首页
多线程-锁

多线程-锁

作者: Berning | 来源:发表于2023-11-14 10:27 被阅读0次
  • OSSpinLock
    1>自旋锁,等待锁的线程会处于忙等(busy-wait)状态,始终占着CPU资源;
    2>实现原理:相当于执行一个while循环;
    3>目前已经不再安全,可能出现优先级反转问题,如果等待锁的线程优先级比较高,它会一直占着CPU资源,优先级低的线程就无法解锁;

多线程实现:利用时间片调度算法
线程优先级:优先级高的线程分配的时间比较多,优先级低的线程分配的时间比较少

#import <libkern/OSAtomic.h>
    //初始化锁
    OSSpinLock lock = OS_SPINLOCK_INIT;
    
    //尝试加锁
    bool result = OSSpinLockTry(&lock);
    
    //加锁
    OSSpinLockLock(&lock);
    
    //解锁
    OSSpinLockUnlock(&lock);

  • os_unfair_lock
    1> iOS10开始取代不安全的OSSpinLock
    2> 从底层来看,等待os_unfair_lock锁的线程,处于休眠状态,而非忙等
#import <os/lock.h>

os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
os_unfair_lock_lock(&lock);
bool result = os_unfair_lock_trylock(&lock);
if(result)
{
    //code here
}
os_unfair_lock_unlock(&lock);

  • pthread_mutex_t
    1>互斥锁,等待锁的线程会处于 休眠状态
#import <pthread.h>
- (void)_init_pthread_mutex:(pthread_mutex_t *)mutex
{
    pthread_mutexattr_t mutexattr;
    pthread_mutexattr_init(&mutexattr);
    pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_DEFAULT);
    pthread_mutex_init(mutex, &mutexattr);
    pthread_mutexattr_destroy(&mutexattr);
}


- (instancetype)init
{
    self = [super init];
    if (self) {
        
        [self _init_pthread_mutex:&_lock];
    }
    return self;
}

- (void)sale_tickets
{
/*
    bool result = pthread_mutex_trylock(& _lock);
    if (result) {
        //code here
    }
*/
    pthread_mutex_lock(& _lock);
    //code here
    pthread_mutex_unlock(& _lock);
}


  • pthread_mutex_t 之RECURSIVE
#import <pthread.h>

@interface pthread_mutex_recursive_test ()

@property(nonatomic,assign)pthread_mutex_t mutex;

@end

@implementation pthread_mutex_recursive_test

- (void)_init_pthread_mutex:(pthread_mutex_t)mutex
{
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    
    pthread_mutex_init(&mutex, &attr);
    
    pthread_mutexattr_destroy(&attr);
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self _init_pthread_mutex:_mutex];
    }
    return  self;
}

- (void)test
{
    pthread_mutex_lock(&_mutex);
    
    static int count = 0;
    if (count < 10) {
        NSLog(@"%d,%s",count, __func__);
        count++;
        [self test];
    }

    
    pthread_mutex_unlock(&_mutex);
}

  • pthread_mutex_t 与pthread_cond_t
#import <pthread.h>
@interface pthread_mutex_cond_test ()

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


@end

@implementation pthread_mutex_cond_test

- (void)_init_pthread_mutex:(pthread_mutex_t)mutex
{
   pthread_mutexattr_t attr;
   pthread_mutexattr_init(&attr);
   pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
   
   pthread_mutex_init(&mutex, &attr);
   
   
   pthread_cond_init(&_cond, NULL);
   
   pthread_mutexattr_destroy(&attr);
}


- (instancetype)init
{
   self = [super init];
   if (self) {
       [self _init_pthread_mutex:_mutex];
       self.data = [NSMutableArray array];
   }
   
   return self;

}

- (void)test
{
   [[[NSThread alloc] initWithBlock:^{
       
       pthread_mutex_lock(&self->_mutex);
       NSLog(@"__remove - begin");

       if (self.data.count == 0) {
           NSLog(@"数组中没有数据");
           pthread_cond_wait(&self->_cond, &self->_mutex);
       }
       
       [self.data removeLastObject];
       NSLog(@"删除了元素");

       pthread_mutex_unlock(&self->_mutex);
       
       }] start];
   
   
   [[[NSThread alloc] initWithBlock:^{
       
       pthread_mutex_lock(&self->_mutex);
       
       [self.data addObject:@"abc"];
       NSLog(@"添加了元素");

       pthread_mutex_unlock(&self->_mutex);
       pthread_cond_signal(&self->_cond);
       
       pthread_cond_broadcast(&self->_cond);

       
       }] start];

}

@end

  • dispatch_semaphore_t
    1> semaphore - 信号量
    2> 信号量的的初始值,可以控制线程并发访问的最大量
    3> 信号量的初始值为1,代表同时只允许1条线程访问资源,保证线程同步
@interface dispatch_semaphore_test ()

@property(nonatomic,strong)dispatch_semaphore_t semaphore;


@end

@implementation dispatch_semaphore_test

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


- (void)est
{
    for (int i = 0; i < 15; i++) {
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(_test) object:nil];
        [thread setName:[NSString stringWithFormat:@"子-%i",I]];
        [thread start];
    }
}

- (void)_test
{
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    
    NSLog(@"%@",[NSThread currentThread]);
    sleep(2);
    dispatch_semaphore_signal(self.semaphore);
}

  • 串行队列
@interface dispatch_queue_serial_test ()
@property(nonatomic,strong)dispatch_queue_t queue;
@property(nonatomic,strong)dispatch_queue_t ticket_queue;
@property(nonatomic,strong)dispatch_queue_t money_queue;

@end

@implementation dispatch_queue_serial_test

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




- (void)test
{
    for (int i = 0; i < 10; i++) {
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(_test:) object:@(i) ];
        [thread setName:[NSString stringWithFormat:@"子-%d",I]];
        [thread start];
    }
}

- (void)_test:(NSNumber *)index
{
    dispatch_sync(self.queue, ^{
        sleep(1);
        NSLog(@"%@",[NSThread currentThread]);
    });

}

@end


  • NSLock

NSLock是对pthread_mutex_t 的封装

@interface NSLock_Test ()

@property(nonatomic,strong)NSLock *tlock;
@end

@implementation NSLock_Test

- (instancetype)init
{
    self = [super init];
    if (self) {

        self.lock = [[NSLock alloc] init];
    }
    
    return self;
}

- (void)sale_tickets
{
    [self.lock lock];
    
  //code here

    
    [self.lock unlock];
    
}

@end

  • NSRecursiveLock

NSRecursiveLock是对pthread_mutex_t递归锁的封装

@interface NSRecursiveLock_Test ()

@property(nonatomic,strong)NSRecursiveLock recursiveLock;



@end

@implementation NSRecursiveLock_Test

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

- (void)test
{
    [self.tickets_lock lock];
    
    static int count = 0;
    if (count < 10) {
        NSLog(@"%d,%s",count, __func__);
        count++;
        [self test];
    }
    
    
    [self.tickets_lock unlock];
}

@end


  • NSCondition

NSCondition是对mutex和cond的封装

@interface NSCondition_Test ()

@property(nonatomic,strong)NSCondition *cond;
@property(nonatomic,strong)NSMutableArray *data;

@end

@implementation NSCondition_Test

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.cond = [[NSCondition alloc] init];
        self.data = [[NSMutableArray alloc] init];
    }
    
    return self;
}

- (void)test
{
    [[[NSThread alloc] initWithBlock:^{
        [self.cond lock];
        NSLog(@"--remove-begin--");
        if (self.data.count == 0) {
//            [self.cond wait];
            [self.cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:3.0] ];
        }
        
        [self.data removeLastObject];
        
        NSLog(@"remove completion");
        [self.cond unlock];
        }] start] ;
    
    
    [[[NSThread alloc] initWithBlock:^{
        [self.cond lock];
        [self.data addObject:@"abc"];
        NSLog(@"add completion");
        [self.cond unlock];
        
        sleep(5);
        NSLog(@"signal will be sent out");
        [self.cond signal];
        NSLog(@"signal has been sent out");

        
//        [self.cond broadcast];
        }] start] ;

}



@end


  • NSConditionLock

NSConditionLock是对NSCondition的进一步封装,可以设置条件值

@interface NSConditionLock_Test ()
@property(nonatomic,strong)NSConditionLock *conditionLock;

@end

@implementation NSConditionLock_Test

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.conditionLock = [[NSConditionLock alloc] initWithCondition:1024];
    }
    
    return self;
}

- (void)test
{
    [[[NSThread alloc] initWithBlock:^{
        [[NSThread currentThread] setName:@"1024"];
        [self.conditionLock lockWhenCondition:1024];
        NSLog(@"%@",[NSThread currentThread]);
        [self.conditionLock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:2]];
        [self.conditionLock unlockWithCondition:2048];
    }] start];
    
    [[[NSThread alloc] initWithBlock:^{
        [[NSThread currentThread] setName:@"2048"];

        [self.conditionLock lockWhenCondition:2048];
        NSLog(@"%@",[NSThread currentThread]);
        [self.conditionLock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];


        [self.conditionLock unlockWithCondition:5012];
    }] start];
    
    [[[NSThread alloc] initWithBlock:^{
        [[NSThread currentThread] setName:@"5012"];

        [self.conditionLock lockWhenCondition:5012];
        NSLog(@"%@",[NSThread currentThread]);
        [self.conditionLock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:3]];

        [self.conditionLock unlock];
        NSLog(@"unLocked finished");
    }] start];

}

@end

  • @synchronized

@synchronized是对mutex递归锁的封装
源码objc4中 objc-sync.mm文件
@ synchronized(obj)内部会生成obj对应的的递归锁,然后进行加锁、解锁操作

@synchronized(self.class)
{
        //code here
}
  • atomic

atomic用于保证setter\getter 方法的原子性操作,相当于在setter/getter方法内部加了线程同步的锁
参考objc4中objc_accessors.mm
不能保证属性的过程是线程安全的

相关文章

  • 起底多线程同步锁(iOS)

    起底多线程同步锁(iOS) 起底多线程同步锁(iOS)

  • 浅析乐观锁、悲观锁与CAS

    乐观锁与悲观锁 处理多线程并发访问最常用的就是加锁,锁又分成乐观锁和悲观锁。 悲观锁 在多线程访问共享资源时,同时...

  • 多线程与锁

    多线程与锁

  • 多线程 (三)iOS中的锁

    ios 多线程--锁

  • 多线程(四)

    上篇多线程(三)我们看了多线程的安全隐患 以及各种锁的简单使用,接下来我们来看看锁的比较、以及自旋锁、互斥锁比较 ...

  • 解决线程同步的方案汇总总结

    这是一篇继上一篇继续介绍多线程同步的博客.(你了解多线程自旋锁、互斥锁、递归锁等锁吗?[https://www.j...

  • OC--各种线程锁

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

  • zookeeperDistributedLock

    分布式锁: 分布式锁是什么? 通常说的锁是单进程多线程的锁,在多线程并发编程中用于线程之间的数据共享 分布式锁 指...

  • 锁与多线程同步的实现

    Java当中的锁都是为了保证多线程同步执行。如果没有锁的话,多线程是异步执行的。 什么是多线程同步? 请看下面的代...

  • iOS线程同步

    线程同步 提到多线程大家肯定会提到锁,其实真正应该说的是多线程同步,锁只是多线程同步的一部分。 多线程对于数据处理...

网友评论

      本文标题:多线程-锁

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