我们如何在swift中使用协议实现并发线程?

我在面试中被问到iOS开发者角色这个问题。

// Please design a read-write task queue where you can tag the reader task with label, // where the the task with the same label should be executed sequentially, and the // tasks with different labels could be executed concurrently. However, the writer // would get the exclusive access where no concurrent task would happen at the // same time with the writer task // For example: protocol ConcurrentQueueWithSerialization { // Submits a labeled task. // All tasks with the same label will be serialized. // Tasks with different labels will run concurrently. // Use this method to submit a "read" operation from a particular reader. func async(with label: String, task: @escaping () -> Void) // Submits a task that will run concurrently with all other tasks regardless of their labels. func async(task: @escaping () -> Void) // Submits a labeled and delayed task. func asyncAfter(deadline: DispatchTime, with label: String, task: @escaping () -> Void) // Submits an unlabeled and delayed task. func asyncAfter(deadline: DispatchTime, task: @escaping () -> Void) // Submits a barrier task. Only one barrier task is allowed to run at a time. // Works as a critical section for the queue. // Use this method to submit a writer task. func asyncBarrier(task: @escaping () -> Void) } class MyDispatchQueue: ConcurrentQueueWithSerialization { //TODO: write your implementation } 

采访者让我在MyDispatchQueue类中实现上述协议。 我试过但找不到解决方案。 请帮帮我。 提前致谢。

以前我建议使用目标队列,但更好的是,创建一个主并发队列,然后为命名队列创建串行队列,然后通过该主并发队列调度所有内容。 与目标队列方法不同,这将使用调度到未命名队列的任务调度分派到命名队列的任务。

有了这个实现,这里有一个例子(一个乐器“兴趣点”的配置文件),我在其中添加了名为“fred”和“ginger”的队列的任务,还有一个添加到未命名队列的任务,然后我添加了一个屏障任务,然后为每个上述队列添加两个任务。

在此处输入图像描述

如您所见,它尊重命名队列的串行性质,未命名的队列是并发的,并且所有这些队列相互并发,但屏障是所有队列的障碍。

 class MyDispatchQueue: ConcurrentQueueWithSerialization { private var namedQueues = [String: DispatchQueue]() private var queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".target", attributes: .concurrent) private let lock = NSLock() private func queue(with label: String) -> DispatchQueue { lock.lock() defer { lock.unlock() } if let queue = namedQueues[label] { return queue } let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + "." + label) namedQueues[label] = queue return queue } func async(with label: String, task: @escaping () -> Void) { queue.async { self.queue(with: label).sync(execute: task) } } func async(task: @escaping () -> Void) { queue.async(execute: task) } func asyncAfter(deadline: DispatchTime, with label: String, task: @escaping () -> Void) { queue.asyncAfter(deadline: deadline) { self.queue(with: label).sync(execute: task) } } func asyncAfter(deadline: DispatchTime, task: @escaping () -> Void) { queue.asyncAfter(deadline: deadline, execute: task) } func asyncBarrier(task: @escaping () -> Void) { queue.async(flags: .barrier, execute: task) } } 

注意,我还同步访问namedQueues数组,以确保namedQueues的线程安全。