我想為執行緒之間的管道資料創建執行緒安全陣列
public class SyncArray<T> {
public var dataArray = [T]()
private var semaphore = DispatchSemaphore(value: 1)
public init() {
}
private func wait() { semaphore.wait() }
private func signal() { semaphore.signal() }
public func count() -> Int {
var count = 0;
wait(); defer { signal() }
count = dataArray.count
return count;
}
public func unshift() -> T? {
var firstEl:T? = nil
wait(); defer { signal() }
if(self.count() > 0){
firstEl = dataArray.removeFirst()
}
return firstEl;
}
public func pop() -> T? {
var lastEl:T? = nil
wait(); defer { signal() }
if(self.count() > 0){
lastEl = dataArray.popLast()
}
return lastEl;
}
public func append(value: T) -> Void {
wait(); defer { signal() }
dataArray.append(value)
}
}
管道資料
let buff = SyncArray<Container>()
DispatchQueue.global().async {
do {
let dataSource = getDataSource()
for i in 0 ..< dataSource.length{
buff.append(value: dataSource[i])
}
}
DispatchQueue.global().async {
while(true) {
let data = buff.unshift()
}
}
這個想法是在執行緒之間管道資料。因某種原因buff.append而buff.unshift陷入僵局
我也試過了
public func count() -> Int {
wait();
count = dataArray.count
signal()
return count;
}
結果一樣。請指教我做錯了什么。我覺得修復應該超級簡單。謝謝!
uj5u.com熱心網友回復:
你的問題是unshift呼叫count. unshift已經持有信號量,但做的第一件事count是 call wait,這會導致死鎖。您在popLast.
由于您已經擁有對該陣列的獨占訪問權,因此您可以簡單地使用其isEmpty屬性。
public func unshift() -> T? {
var firstEl:T? = nil
wait(); defer { signal() }
if !dataArray.isEmpty {
firstEl = dataArray.removeFirst()
}
return firstEl;
}
public func pop() -> T? {
var lastEl:T? = nil
wait(); defer { signal() }
if !dataArray.isEmpty {
lastEl = dataArray.popLast()
}
return lastEl;
}
您也可以DispatchSemaphore用 a替換您,NSRecursiveLock因為您不需要信號量的計數行為。NSRecursiveLock可以被lock同一個執行緒多次編輯而不會導致死鎖。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/337347.html
上一篇:如何使用遞回函式操作串列?
