如何终止从与Process(NSTask)相关的Pipe(NSPipe)读取的所有线程?

时间:2017-06-29 19:15:48

标签: xcode multithreading cocoa appkit nstask

我正在编写一个MacOS / Cocoa应用程序,该应用程序使用在后台线程上启动Process(以前称为NSTask)实例的通用配方来监视远程日志文件并读取stdout该流程通过Pipe(正式为NSPipe)列出,如下所示:

class LogTail {
  var process : Process? = nil

  func dolog() {

    //
    // Run ssh fred@foo.org /usr/bin/tail -f /var/log.system.log
    // on a background thread and monitor it's stdout.
    //
    let processQueue = DispatchQueue.global(qos: .background)
    processQueue.async {
       //
       // Create process and associated command.
       // 
       self.process = Process()
       process.launchPath = "/usr/bin/ssh"
       process.arguments = ["fred@foo.org",
                            "/usr/bin/tail", "-f",
                            "/var/log.system.log"]
       process.environment = [ ... ]

       //
       // Create pipe to read stdout of command as data is available
       //
       let pipe = Pipe()
       process.standardOutput = pipe
       let outHandle = pipe.fileHandleForReading
       outHandle.readabilityHandler = { pipe in
         if let string = String(data: pipe.availableData,
                                encoding: .utf8) {
            // write string to NSTextView on main thread
         }
       } 

       //
       // Launch process and block background thread 
       // until process complete.
       //
       process.launch()
       process.waitUntilExit()

       //
       // What do I do here to make sure all related
       // threads terminate?
       //
       outHandle.closeFile() // XXX
       outHandle.readabilityHandler = nil // XXX
   }
}

一切都很有效,但当进程退出(通过process.terminate杀死)时,我注意到(通过Xcode的Debug Navigator和Console应用程序)有多个线程消耗了180%或更多的线程中央处理器!?!

这个CPU泄漏来自哪里?

我投入outHandle.closeFile()(参见上面标记为XXX的代码)并将CPU使用率降低到几个百分点,但线程仍然存在!我做错了什么或如何确保所有相关的线程终止(我更喜欢优雅的终止,即线程主体完成执行)!?

有人在差不多5年前发布了similar question

更新

NSFileHandle's readabilityHandler的文档说:

  

要停止读取文件或套接字,请将此属性的值设置为   零。这样做会取消调度源并清理文件   妥善处理结构。

所以设置outHandle.readabilityHandler = nil似乎也解决了这个问题。

即使我似乎解决了这个问题,但我真的不明白这个巨大的CPU漏洞来自哪里 - 非常神秘。

0 个答案:

没有答案