首页 > 解决方案 > DispatchSemaphore 是否等待特定的线程对象?

问题描述

我今天实现了一个信号量,它提出了一些关于信号量、线程和队列的问题。我的以下符号准确吗?

let semaphore = DispatchSemaphore(value: 1)
let serialQueue = DispatchQueue(label: "serial")

someAsyncMethod {

    serialQueue.async {

        // When someAsyncMethod returns, this queue, behind the scenes,
        // creates a Thread/NSThread object and approaches the
        // semaphore and it is this thread object that decrements
        // the semaphore counter.

        // The next time someAsyncMethod returns, a new thread object
        // is created behind the scenes (by the queue) and this thread
        // object is made to wait until something (anything) signals
        // it is done.

        semaphore.wait()

        // do work...
        someMethod()

    }

}

func someMethod() {

    // do work...

    // This task may ultimately be on a different thread than
    // where it started despite being in the same queue
    // (since not every task is guaranteed to run on the same thread)
    // but it doesn't matter, any object can signal the semaphore.

    semaphore.signal()

}
  1. 信号量是否响应特定的线程对象/实例?
  2. 每次someAsyncMethod返回并进入队列时是否都会创建一个新的线程对象/实例?

标签: iosswiftgrand-central-dispatchsemaphore

解决方案


信号量不是特定于线程的。重点是在线程之间进行协调,因此它们必须可供多个线程使用。

在这种特定情况下,不需要信号量(如果这些是唯一用途),因为您使用的是串行队列。根据定义,串行队列一次只允许其中一个排队的任务以先进先出的顺序运行。也就是说,第二个任务不需要等待信号量来避免与第一个任务同时运行,因为在第一个任务完成之前它甚至不允许启动。

当您将任务异步放入队列时,调用代码可以立即继续。该任务更像是被放入数据结构(队列)中的数据对象。Grand Central Dispatch 使用线程池将任务从队列中弹出并执行。是否必须创建新线程取决于池中是否已经有足够的空闲线程。


推荐阅读