GCD with static functions of a struct

前端 未结 2 1134
醉酒成梦
醉酒成梦 2020-12-20 03:33

how\'d you apply thread safe functionality to static functions of a struct

class SingleSome {

    struct Static {
        private static var instance: Singl         


        
相关标签:
2条回答
  • 2020-12-20 03:54

    Use a semaphore, dispatch_sync isn't appropriate because you need a synchronous return value from getInstance:

    class SingleSome {
    
        struct Static {
            private static var instance: SingleSome?
            private static let lock = dispatch_semaphore_create(1)
    
            //need barrier sync
            static func getInstance(block: () -> SingleSome) -> SingleSome {
                dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)
                var value = instance
                if value == nil {
                    instance = block()
                    value = instance
                }
                dispatch_semaphore_signal(lock)
                return value!
            }
    
            static func remove() { //need barrier sync
                dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)
                instance = nil
                dispatch_semaphore_signal(lock)
            }
        }
    
    }
    

    Also note that as written this is subject to deadlocks if block results in either remove or getInstance being called as dispatch_semaphore_t is not thread recursive.

    0 讨论(0)
  • 2020-12-20 03:59

    You can use a private serial queue to ensure that only one thread can be in any of the critical sections at any instant.

    class SingleSome {
    
        struct Static {
            private static let queue = dispatch_queue_create("SingleSome.Static.queue", nil)
            private static var instance: SingleSome?
    
            static func getInstance(block: () -> SingleSome) -> SingleSome {
                var myInstance: SingleSome?
                dispatch_sync(queue) {
                    if self.instance == nil {
                        self.instance = block()
                    }
                    myInstance = self.instance
                }
                // This return has to be outside the dispatch_sync block,
                // so there's a race condition if I return instance directly.
                return myInstance!
            }
    
            static func remove() {
                dispatch_sync(queue) {
                    self.instance = nil
                }
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题