繁体   English   中英

Swift中的并发和锁定

[英]Concurrency and lock in Swift

前提

我们都知道宇宙中有很多数字坏数字

我有以下同步功能

func isGood(number:Int) -> Bool {
    // synchronous connection
    // ...
    // returns a Bool
}

当然,我不是在这里提供秘密实现,但你应该知道它执行同步互联网连接并确实返回

  • true :如果作为参数收到的Int是一个“好数字”
  • false :否则

问题

现在,假设从0到99的100个整数,我想知道它们中至少有51个是好数字。

同步方法

我可以写这样的东西。

func majorityIsGood() -> Bool {
    var count = 0
    for i in 0...99 {
        if isGood(i) {
            count++
            if count > 50 {
                return true
            }
        }
    }
    return false
}

但是执行100(在最坏的情况下)同步调用isGood将需要太多时间。 我需要尽快得到答案。

异步方法

我更喜欢这样的东西

func majorityIsGood(completion:(good:Bool) -> ()) {
    var goodNums = 0
    var badNums = 0
    var resultFound = false

    for i in 0...99 {
        dispatch_async(DISPATCH_QUEUE_CONCURRENT) {

            let isGood = isGood(i)

            // lineA
            // begin lock on (resultFound)
            if !resultFound {
                if isGood {
                    goodNums++
                } else {
                    badNums++
                }
                if goodNums > 50 || badNums >= 50 {
                    resultFound = true
                    completion(good: goodNums > 50)
                }
            }
            // end lock on (resultFound)
            // lineB
        }
    }
}

问题

  1. 如何保证同步访问Swift中lineAlineB之间的代码块?
  2. 最后,一旦我得到结果,是否有可能杀死仍在处理的并发闭包?

先感谢您。

  1. serial queue可用于同步对特定资源的访问。
  2. 我不确定。 如果有办法杀死正在调度的并发操作。 但是,如果你只是想阻止它们。 看看NSOperation取消。

这是代码

func majorityIsGood( completion: ((good:Bool) -> Void) ) {

    var goodNums = 0
    var badNums = 0
    var resultFound = false

    let serialQueue = dispatch_queue_create("com.unique.myQueue", DISPATCH_QUEUE_SERIAL)

    for i in 0...99 {
        dispatch_async(DISPATCH_QUEUE_CONCURRENT) {

            let _isGood = isGood(i)

            // lineA
            dispatch_async(serialQueue){
                if !resultFound {
                    if _isGood {
                        goodNums++
                    } else {
                        badNums++
                    }
                    if goodNums > 50 || badNums >= 50 {
                        resultFound = true
                        completion(good: goodNums > 50)
                    }
                }
            }
            // lineB
        }
    }
}

建立在巨人的肩膀上!

  1. 我会用https://github.com/ReactiveCocoa/ReactiveCocoa/blob/v3.0-RC.1/ReactiveCocoa/Swift/Atomic.swift激发自己,并使用他们的lock / unlock机制。
  2. 据我所知,没有办法“杀死”闭包 - 这听起来像是使用NSOperation数组提供取消机制的情况(尽管应该注意到它实际上取决于你检查在你的NSOperation中的适当点处的isCancelled标志,这样你就可以停止正在做的任何工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM