如何快速使线程安全代码块

时间:2018-08-10 07:08:40

标签: ios swift xcode multithreading locking

我尝试了多个关于stackoverflow的解决方案/答案,但是没有一个对我有用。其中一些如下:

https://stackoverflow.com/a/30495424/3145189

Is this safe to call wait() of DispatchSemaphore several times at one time?

https://stackoverflow.com/a/37155631/3145189

我正在尝试实现一个非常简单的功能,无论从哪个线程调用它,代码块或函数都应按顺序执行。

我的示例代码:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

   DispatchQueue.global().async {
        self.testLog(name:"first")
    }
    DispatchQueue.global().async {
        self.testLog(name:"second")
    }

    DispatchQueue.main.async {
        self.testLog(name: "mainthread")
    }
}


func testLog(name:String) -> Void {
        for i in 1..<1000 {
            print("thread test \(i) name =\(name)")
        }

    }

所以输出应该像-

第一次线程调用

线程测试1名称= first

线程测试2名称= first

线程测试3名称= first

线程测试999 name = first

第二个线程调用

线程测试1名称=秒

线程测试2名称= second

线程测试999 name = second

主线程调用

线程测试1名称= mainthread

线程测试2名称= mainthread

线程测试999名称= mainthread

如果在第一个线程上调用了该函数,则该功能应仅继续对第一个线程进行打印日志。线程的顺序可能会有所不同,我不在乎,即使先打印主线程日志,然后再打印第二和第一个无关紧要的日志也应该进行分组。

2 个答案:

答案 0 :(得分:3)

这将顺序执行调用。 保留对serialQueue的引用,您可以从任何线程提交块。

let serialQueue = DispatchQueue(label: "serial_queue")

    serialQueue.async {
        self.testLog(name: "first")
    }
    serialQueue.async {
        self.testLog(name: "second")
    }

    serialQueue.async {
        self.testLog(name: "third")
    }

答案 1 :(得分:0)

  

我正在尝试实现一个非常简单的功能,无论从哪个线程调用它,代码块或函数都应按顺序执行。

要串行执行,请使用Dispatch串行队列。如果您正在编写类或结构,则可以在类/结构级别使用static let来存储您的序列化函数可以分派到的队列。在这种情况下,static let相当于某些语言中的“类变量”。

如果您使用(Objective-)C编写此类变量,那么也可以在函数级别声明该变量,即具有全局生存期但范围限于函数内的变量。 Swift在函数中不支持这些,但是您可以将结构的作用域限定为函数...

func testLog(name:String) -> Void
{
   struct LocalStatics
   {
      static let privateQueue = DispatchQueue(label: "testLogQueue")
   }

   // run the function body on the serial queue - could use async here
   // and the body would still run not interleaved with other calls but
   // the caller need not wait for it to do so 
   LocalStatics.privateQueue.sync {
      for i in 1..<1000
      {
         print("thread test \(i) name =\(name)")
      }
   }
}

(有关Swift中“局部静态”的讨论,请参见this SO Q&A