我们如何在swift中使用协议实现并发线程?(How can we implement concurrency thread using protocol in swift? [closed])

编程入门 行业动态 更新时间:2024-10-17 21:20:37
我们如何在swift中使用协议实现并发线程?(How can we implement concurrency thread using protocol in swift? [closed])

我在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类中实现上述协议。 我试过但找不到解决方案。 请帮帮我。 提前致谢。

I was asked this question in interview for iOS developer role.

// 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 }

Interviewer asked me to implement above protocol in MyDispatchQueue class. I tried but could not find solution. Please help me. Thanks in advance.

最满意答案

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

在这个实现中,下面是一个示例(一个工具“兴趣点”配置文件),其中我添加了名为“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的线程安全。

Previously I suggested using target queues, but even better, create a primary concurrent queue, and then create serial queues for the named queues, and then dispatch everything through that primary concurrent queue. Unlike the target queue approach, this will honor the scheduling of tasks dispatched to the named queues with those dispatched to the unnamed queue.

With that implementation, here's an example (an Instruments "Points of Interest" profile) of this where I added tasks for queues named "fred" and "ginger" and also one which was added to an unnamed queue, I then added a barrier task, and then added two more tasks to each of the aforementioned queues.

enter image description here

As you can see, it respects the serial nature of the named queues, the unnamed queue is concurrent, and all these queues are concurrent with respect to each other, but the barrier is a barrier across all the queues.

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) } }

Note, I also synchronize access to the namedQueues array, to ensure the thread-safety of this class.

更多推荐

本文发布于:2023-07-22 09:46:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1219096.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线程   协议   如何在   swift   implement

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!