2017-08-11 133 views
1

我在iOS开发人员角色的面试中被问到这个问题。如何在swift中使用协议实现并发线程?

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

+0

SO不是代码写入服务。你有什么尝试?你遇到了什么问题? – Alexander

+0

你的问题只包含要求 - 它并没有显示你方的努力来解决这个问题。请将您的尝试加入这个问题 - 因为本网站不是免费的“我们做您的(家)工作”服务。除此之外:请转到[帮助]了解如何/在这里问什么。谢谢! – GhostCat

回答

6

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

在这个实现中,下面是一个示例(一个工具“兴趣点”配置文件),其中我添加了名为“fred”和“ginger”的队列的任务,还添加了一个未命名的队列,然后我增加了一个屏障任务,然后再向上述每个队列添加两个任务。

enter image description here

正如你所看到的,它尊重命名的队列的串行特性,无名队列是并发的,而所有这些队列是同时相对于彼此,但障碍是所有的障碍队列。

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阵列,以保证这个类的线程安全。