2017-11-03 58 views
1

假设我们有多个线程发布打印。 在下载东西时,通常如下:如何防止线程打印在控制台中混合输出?

let url = self.url 
print("loadPreview(\(source) for \(url)): ↝start loading \(self.url") 
let task = session.downloadTask(with: url) { 
    (localUrl, response, error) in 
    print("loadPreview(\(source) for \(url)): == \(self.url") 
} 

有没有什么办法,使打印原子和防止输出如下?

loadPreview(WSJ for www.wsj.co⟷TloadPreview(9loadPreview(appleins for appleinsid⟷n-messages):  ↝start loading http://app⟷n-messages 
+0

的可能的复制[ Python 2.7:打印线程安全](https://stackoverflow.com/questions/7877850/python-2-7-print-thread-safe) –

回答

1

快速入门只是在您的打印件周围使用NSLock。例如,你可以定义一个原子打印功能为:

private let printLock = NSLock() 

func aprint(_ message: String){ 
    printLock.lock() 
    defer { printLock.unlock() } 
    print(message) 
} 

,并使用它像标准print功能:

aprint(“This will print atomically!”) 

你也可以使用串行DispatchQueue实现了类似的结果将您的打印电话也序列化为。例如:

private let printQueue = DispatchQueue(label: "aprint", qos: .utility) 

func aprint(_ message: String){ 
    printQueue.async { 
     print(message) 
    } 
} 

该解决方案提供了更好的性能主要得益于async通话。这确保了调用线程将而不是阻塞,直到获取锁(并且相应的print完全执行)。但是,要明确,这个解决方案也是完全原子的。

(根据记录,只需使用DispatchQueue.main可能会表现得古怪如果调用代码是主队列运行。)

我会建议选择第二种方案;)

+0

这个解决方案会不同于我已经测试?,又名:objc_sync_enter(self) ;打印(文本); objc_sync_exit(个体); –

+0

结果相同*如果*所有'print'调用都使用与锁相同的对象(即'self' var你的代码)。否则,当从不同的对象打印时,您仍可能会看到混合输出。无论如何,我建议你将选定的解决方案包装在漂亮的API中,以提高代码的可读性;) –

+0

...但基于DispatchQueue的解决方案可能会提供稍好的性能;) –

相关问题