美文网首页
互斥锁和自旋锁

互斥锁和自旋锁

作者: ImmortalSummer | 来源:发表于2019-08-13 10:56 被阅读0次

当多个线程访问同一个变量时, 很容易引发数据安全问题. 可以添加 互斥锁或者自旋锁解决这个问题.

自旋锁
当一个线程获取这个锁以后, 其他线程会抑制循环在哪里查看该锁是否被释放, 该锁不适合用于锁定保持时间过长的情况, 且消耗较大的性能.

互斥锁
当一个线程获得这个锁以后, 其他线程会被阻塞, 知道该锁被释放.

原子属性
atmoic/nonatmoic

atmoic:原子属性,为系统默认的属性,会为修饰的成员变量的setter方法自动加锁(自旋锁),使得线程安全,但较为消耗资源,效率相对低些。是一种单写多度的多线程技术,可能出现脏数据。

nonatomic:非原子属性,开发中最常用的属性,不会为修饰的成员变量的setter方法加锁,虽然线程不安全,但效率高.

互斥锁示例:

@interface ViewController (){
    int index;
}

//...

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self testLock:@"a"];
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self testLock:@"b"];
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self testLock:@"c"];
    });
}

-(void)testLock:(NSString *)flag{
    NSLog(@"flag:%@ 当前线程:%@",flag,[NSThread currentThread]);
    
    @synchronized (@"token") {
        for (int i=0; i<3; i++) {
            index++;
            sleep(0.1);
            NSLog(@"flag:%@ %d", flag, index);
        };
    }
}

-(void)testUnlock:(NSString *)flag{
    NSLog(@"flag:%@ 当前线程:%@",flag,[NSThread currentThread]);
    
    for (int i=0; i<3; i++) {
        index++;
        sleep(0.1);
        NSLog(@"flag:%@ %d", flag, index);
    };
}

/* 加锁 testLock 运行结果
2019-08-13 10:55:32.382984+0800 自旋锁和互斥锁[96408:4773768] flag:c 当前线程:<NSThread: 0x600002a7c600>{number = 5, name = (null)}
2019-08-13 10:55:32.383005+0800 自旋锁和互斥锁[96408:4773766] flag:a 当前线程:<NSThread: 0x600002a2be80>{number = 3, name = (null)}
2019-08-13 10:55:32.383020+0800 自旋锁和互斥锁[96408:4773769] flag:b 当前线程:<NSThread: 0x600002a07f40>{number = 4, name = (null)}
2019-08-13 10:55:32.383308+0800 自旋锁和互斥锁[96408:4773768] flag:c 1
2019-08-13 10:55:32.383444+0800 自旋锁和互斥锁[96408:4773768] flag:c 2
2019-08-13 10:55:32.383612+0800 自旋锁和互斥锁[96408:4773768] flag:c 3
2019-08-13 10:55:32.383771+0800 自旋锁和互斥锁[96408:4773769] flag:b 4
2019-08-13 10:55:32.383909+0800 自旋锁和互斥锁[96408:4773769] flag:b 5
2019-08-13 10:55:32.384102+0800 自旋锁和互斥锁[96408:4773769] flag:b 6
2019-08-13 10:55:32.384352+0800 自旋锁和互斥锁[96408:4773766] flag:a 7
2019-08-13 10:55:32.384701+0800 自旋锁和互斥锁[96408:4773766] flag:a 8
2019-08-13 10:55:32.385032+0800 自旋锁和互斥锁[96408:4773766] flag:a 9
*/
/* 不加锁 testUnlock 运行结果
2019-08-13 10:55:58.147531+0800 自旋锁和互斥锁[96415:4774371] flag:c 当前线程:<NSThread: 0x6000022b7940>{number = 4, name = (null)}
2019-08-13 10:55:58.147584+0800 自旋锁和互斥锁[96415:4774370] flag:b 当前线程:<NSThread: 0x6000022943c0>{number = 5, name = (null)}
2019-08-13 10:55:58.147586+0800 自旋锁和互斥锁[96415:4774372] flag:a 当前线程:<NSThread: 0x600002290380>{number = 3, name = (null)}
2019-08-13 10:55:58.147786+0800 自旋锁和互斥锁[96415:4774372] flag:a 3
2019-08-13 10:55:58.147786+0800 自旋锁和互斥锁[96415:4774370] flag:b 3
2019-08-13 10:55:58.147787+0800 自旋锁和互斥锁[96415:4774371] flag:c 3
2019-08-13 10:55:58.147914+0800 自旋锁和互斥锁[96415:4774372] flag:a 4
2019-08-13 10:55:58.147953+0800 自旋锁和互斥锁[96415:4774370] flag:b 5
2019-08-13 10:55:58.147986+0800 自旋锁和互斥锁[96415:4774371] flag:c 6
2019-08-13 10:55:58.148256+0800 自旋锁和互斥锁[96415:4774372] flag:a 7
2019-08-13 10:55:58.148509+0800 自旋锁和互斥锁[96415:4774371] flag:c 8
2019-08-13 10:55:58.149224+0800 自旋锁和互斥锁[96415:4774370] flag:b 9
*/

NSLock

@interface ViewController (){
    NSLock *lock;
}

-(void)testNSLock:(NSString *)flag{
    NSLog(@"flag:%@ 当前线程:%@",flag,[NSThread currentThread]);
    
    //多个线程要用同一个锁
    if (!lock) {
        lock = [NSLock new];
    }
    
    [lock lock];
    for (int i=0; i<3; i++) {
        index++;
        sleep(0.1);
        NSLog(@"flag:%@ %d", flag, index);
    };
    [lock unlock];
}

自旋锁示例:(失败的)

#import <os/lock.h>

os_unfair_lock_t unfairLock = &(OS_UNFAIR_LOCK_INIT);
os_unfair_lock_lock(unfairLock);
//lock coding 要加锁的代码
os_unfair_lock_unlock(unfairLock);
#import <libkern/OSAtomic.h>

OSSpinLock lock = OS_SPINLOCK_INIT;
OSSpinLockLock(&lock);
//lock coding 要加锁的代码
OSSpinLockUnlock(&lock);

//OSSpinLock ios10开始过期了

自旋锁搞了搞几次都不成, 反正性能也不好, 不用了哈哈哈

相关文章

  • CLH并发队列

    1 什么是自旋锁和互斥锁? 由于CLH锁是一种自旋锁,那么我们先来看看自旋锁是什么? 自旋锁说白了也是一种互斥锁,...

  • iOS面试题与核心基础之线程同步(锁,串行队列,信号量,@syn

    锁 iOS多线程锁有两类 自旋锁 和 互斥锁自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。资源已...

  • iOS 锁

    同步锁 自旋锁 互斥锁

  • iOS底层探索-多线程锁

    多线程的锁大致可分为两大类:互斥锁、自旋锁;也可以分为三类:互斥锁、自旋锁、读写锁。 一、互斥锁:互斥+同步(强调...

  • 线程锁

    1.常见的锁包括:互斥锁,自旋锁。 2.互斥锁是指锁的类型,自旋锁是指锁的实现方式。 3.互斥锁:当上...

  • 自旋锁 和 互斥锁

    自旋锁 和 互斥锁 Pthreads提供了多种锁机制: (1) Mutex(互斥量):pthread_mutex_...

  • 多线程复习

    自旋锁 & 互斥锁 自旋锁:atomic、OSSpinLock、dispatch_semaphore_t临界区加锁...

  • iOS 开发中加锁

    [1].OSSpinLock 自旋锁 [1]自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被...

  • iOS 多线程面试题(自旋锁与互斥锁)

    自旋锁与互斥锁 自旋锁: 是一种用于保护多线程共享资源的锁,与一般互斥锁(mutex)不同之处在于当自旋锁尝试获取...

  • iOS中的自旋锁与互斥锁

    一:自旋锁与互斥锁 自旋锁:是一种用于保护多线程共享资源的锁,与一般互斥锁(mutex)不同之处在于当自旋锁尝试获...

网友评论

      本文标题:互斥锁和自旋锁

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