b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

线程安全: 互斥锁和自旋锁(10种类型)

电脑杂谈  发布时间:2020-05-06 03:13:54  来源:网络整理

多线程mutex_线程池与线程_c# 线程 线程池

没有并发,没有编程. 对于多线程,很难绕过锁.

iOS开发中两种常见的锁类型:

1. 互斥锁: 一次只有一个线程可以获取一个互斥锁,其余线程被挂起.

2. 自旋锁: 一个线程获得自旋锁后,其他线程将继续循环并尝试添加锁. 当超出限制并且未成功获得锁定时,线程将被挂起.

自旋锁更适合保留时间较短的锁持有人,实际使用中更多的排他锁.

1. 互斥体,信号量

1. 符合NSLocking协议的四种类型的锁

四种类型的锁是:

NSLock,NSConditionLock,NSRecursiveLock,NSCondition

NSLocking协议

public protocol NSLocking {    
    public func lock()
    public func unlock()
}

这里是从多个售票点同时售票的示例

线程池与线程_c# 线程 线程池_多线程mutex

var ticket = 20
var lock = NSLock()
    
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
    let thread1 = Thread(target: self, selector: #selector(saleTickets), object: nil)
    thread1.name = "售票点A"
    thread1.start()
    
    let thread2 = Thread(target: self, selector: #selector(saleTickets), object: nil)
    thread2.name = "售票点B"
    thread2.start()
}
    
@objc private func saleTickets() {
    while true {
        lock.lock()
        Thread.sleep(forTimeInterval: 0.5) // 模拟延迟
        if ticket > 0 {
            ticket = ticket - 1
            print("\(String(describing: Thread.current.name!)) 卖出了一张票,当前还剩\(ticket)张票")
            lock.unlock()
        }else {
            print("oh 票已经卖完了")
            lock.unlock()
            break;
        }
    }
}

顾名思义,这两种方法是在遵守协议后实现的lock()和unlock()方法.

此外,NSLock,NSConditionLock,NSRecursiveLock和NSCondition具有自己的实现:

1. 除了NSCondition之外,所有三种类型的锁都有两种方法:

    // 尝试去锁,如果成功,返回true,否则返回false
    open func `try`() -> Bool
    // 在limit时间之前获得锁,没有返回NO
    open func lock(before limit: Date) -> Bool

2. NSCondition条件锁:

    // 当前线程挂起
    open func wait()
    // 当前线程挂起,设置一个唤醒时间
    open func wait(until limit: Date) -> Bool
    // 唤醒在等待的线程
    open func signal()
    // 唤醒所有NSCondition挂起的线程
    open func broadcast()

在调用wait()之后,NSCondition实例将使用现有的锁来解锁当前线程,然后使该线程进入睡眠状态,当信号()通知时,该线程被唤醒,然后当前线程被锁定,因此看起来似乎wait()一直持有该锁,但是根据Apple文档中的说明,直接将wait()视为线程锁不能保证线程安全.

3. NSConditionLock条件锁:

NSConditionLock是在NSCondition的帮助下实现的. 在NSCondition的基础上,添加了一个有限条件,并且定制程度可以高于NSCondition.

    // 锁的时候还需要满足condition
    open func lock(whenCondition condition: Int)
    // 同try,同样需要满足condition
    open func tryLock(whenCondition condition: Int) -> Bool
    // 同unlock,需要满足condition
    open func unlock(withCondition condition: Int)
    // 同lock,需要满足condition和在limit时间之前
    open func lock(whenCondition condition: Int, before limit: Date) -> Bool

4. NSRecurisiveLock递归锁:

线程池与线程_c# 线程 线程池_多线程mutex

定义一个锁,该锁可以多次锁定同一线程而不会导致死锁.

提供的几种方法类似于NSLock.

2. GCD DispatchSemaphore和围栏功能

1. DispatchSemaphore信号量:

DispatchSemaphore中的信号量可以解决资源抢占的问题,并支持信号通知和等待. 发送信号通知时,信号量为+1;每当发送等待信号时,信号量为-1,如果信号为0,则信号将处于等待状态. 它将一直执行到信号量大于0为止. 因此,我们通常将DispatchSemaphore的值设置为1.

下面给出了DispatchSemaphore封装类

class GCDSemaphore {
    // MARK: 变量
    fileprivate var dispatchSemaphore: DispatchSemaphore!
    // MARK: 初始化
    public init() {
        dispatchSemaphore = DispatchSemaphore(value: 0)
    }
    public init(withValue: Int) {
        dispatchSemaphore = DispatchSemaphore(value: withValue)
    }
    // 执行
    public func signal() -> Bool {
        return dispatchSemaphore.signal() != 0
    }
    public func wait() {
        _ = dispatchSemaphore.wait(timeout: DispatchTime.distantFuture)
    }
    public func wait(timeoutNanoseconds: DispatchTimeInterval) -> Bool {
        if dispatchSemaphore.wait(timeout: DispatchTime.now() + timeoutNanoseconds) == DispatchTimeoutResult.success {
            return true
        } else {
            return false
        }
    }
}


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-200179-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 郭彩萍
      郭彩萍

      期待演员杨洋带来更好的作品

    • 日高惠美
      日高惠美

      没用

    • 冯基平
      冯基平

      包装好的话里面干燥不可能生虫

    热点图片
    拼命载入中...