前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于多线程中的几把锁

关于多线程中的几把锁

作者头像
大话swift
发布2019-07-04 11:22:02
7310
发布2019-07-04 11:22:02
举报
文章被收录于专栏:大话swift

之前lz说后续会继续做SQLite的操作,在lz做版本swift版本操作SQLite过程中遇到了多线程访问的问题,今天就给大家梳理一下其中对共享数据多线程操作中的?,或者是iOS开发中的几种?甚至这些锁很多实用IT开发中……

1 自旋锁

何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。

说白了自旋锁锁有两个功能:1 共享资源加锁 2 共享资源被其他加锁,则原地等待不停查询

代码语言:javascript
复制
func spinLock(){
    /**
     自旋锁
     lock/unlock要成对出现
     **/
    var ossLock = os_unfair_lock_s.init(_os_unfair_lock_opaque: UInt32(OS_SPINLOCK_INIT))
    //    var number = 0
    for i in 0..<100 {
        DispatchQueue.global().async {
            os_unfair_lock_lock(&ossLock)
            //            os_unfair_lock_trylock(&ossLock)
            //            os_unfair_lock_unlock(&ossLock)
            number = number+1
            print(number,"\t",i, "spinLock")
            os_unfair_lock_unlock(&ossLock)
        }
    }
}

2 信号量?

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。

说起信号量有一个很直观有趣的故事:

以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。

代码语言:javascript
复制
func semaphore(){
    let  signalCount = 1
    let semaphore = DispatchSemaphore(value: signalCount)
    
    let timeout : DispatchTime = DispatchTime.init(uptimeNanoseconds: NSEC_PER_SEC * UInt64(signalCount))
    for i in 0...200 {
        //        queue.async(execute: DispatchWorkItem.init(block: {
        //            semaphore.wait(timeout: timeout)
        //            number = number + 1
        //            print(number, "\t", i, "semaphore")
        //            semaphore.signal()
        //        }));
        DispatchQueue.global().async {
            let result = semaphore.wait(timeout: timeout)
            switch result {
            case .success:
                number = number + 1
                print(number, "\t", i, "semaphore")
                break
            default:
                print(number, "\t", i, "等待失败semaphore")
                
            }
            semaphore.signal()
        }
    }
    
}

3 pthread_mutex_t(p锁)

p锁是Linux平台的锁,在此我们不多介绍,直接上代码

代码语言:javascript
复制
func pthreadMutex(){
    
    var mutex : pthread_mutex_t =  pthread_mutex_t()
    var attr:Optional<pthread_mutexattr_t> = nil
    
    //进行初始化可以添加附加属性
    attr = pthread_mutexattr_t()
    
    if attr == nil {
        pthread_mutex_init(&mutex, nil) //此时如果用于递归中则会形成死锁
        
        
        DispatchQueue.global().async {
            pthread_mutex_lock(&mutex)
            number = number + 1
            print(number,"111")
            pthread_mutex_unlock(&mutex)
        }
        DispatchQueue.global().async {
            pthread_mutex_lock(&mutex)
            number = number + 1
            print(number,"222")
            pthread_mutex_unlock(&mutex)
        }
        
        
    }else{
        pthread_mutexattr_init(&attr!)
        pthread_mutexattr_settype(&attr!, PTHREAD_MUTEX_RECURSIVE)
        pthread_mutex_init(&mutex,  &attr!)
        
        var value = 5
        DispatchQueue.global().async {
            
            func test(_ v: Int) ->Void{
                pthread_mutex_lock(&mutex)
                if v > 0 {
                    print("value= ",v)
                    test(v-1)
                }
                pthread_mutex_unlock(&mutex)
            }       
            test(value)
        }
    }   
}

p锁是众多锁中很少能订制的一把锁,从上栗中我们看到即可用于互斥也能进行配置达到递归锁的目的,大家可以试试,在默认情况下欲行递归是否形成死锁…

4 condtion

这个不多多说,想加锁解锁需要满足条件才可以,咱们直接上代码

代码语言:javascript
复制
func condtion(){
    
    let  condtion = NSConditionLock.init(condition: 0) //尝试加锁会从whenCondition:0的位置开始
    var p = 100
    DispatchQueue.global().async {
        condtion.lock(whenCondition: 1)
        print("finished")
        condtion.unlock(withCondition: p)
    }
    
    DispatchQueue.global().async {
        condtion.lock(whenCondition: 0)
        p = 1
        print("start")
        condtion.unlock(withCondition: p)
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大话swift 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档