iOS 개발을 하면서 스레드를 직접 생성해서 해야하는 작업은 별로 없었다.
DispatchQueue, OperationQueue 를 이용해 대부분의 작업을 할 수 있지만
특정 하나의 스레드에서만 작업되기를 원한다면 스레드를 직접 생성해서 해당 스레드에서 작업이 되도록 해야 한다.
앱내에서 Realm 관련 작업을 했는데 해당 모델의 Read/Write 가 하나의 스레드에서 되어야 해서
특정 스레드를 생성해서 작업해야 했다.
다음은 스레드를 생성하고 작업대상을 추가하여 생성된 스레드에서만 작업이 되는 간단한 예시이다.
let t = CustomThread()
for i in 0 ..< 5 {
t.push(Entry(index: i))
}
DispatchQueue.global().async {
for i in 5 ..< 10 {
t.push(Entry(index: i))
}
}
// 스레드가 처리할 엔트리
class Entry {
private var index = 0
init(index: Int) {
self.index = index
}
func work() {
print("working, entry index \(index) thread \(Thread.current)")
}
}
스레드가 처리할 엔트리를 넣을때와 실제 작업을 하기 위해 엔트리를 뺄 때
condition 객체를 이용하여 엔트리를 넣는 스레드와 엔트리를 빼는 스레드(CustomThread) 동시 접근을 막는다.
class CustomThread {
private var serialQueue = DispatchQueue(label: "SerialQueue")
private var thread: Thread!
private var condition = NSCondition()
private var entries = [Entry]()
init() {
thread = Thread(target: self, selector: #selector(self.main(_:)), object: nil)
thread.start()
}
@objc
func main(_ param: Any?) {
while !Thread.current.isCancelled {
condition.lock()
if entries.isEmpty {
condition.wait()
}
for entry in entries {
entry.work()
}
entries.removeAll()
condition.unlock()
}
}
func push(_ entry: Entry) {
func push() {
condition.lock()
entries.append(entry)
condition.signal()
condition.unlock()
}
serialQueue.async {
push()
}
}
}
결과는 아래와 같다. 0~4 인덱스는 메인스레드에서 넣고 5~9 인덱스는 임의의 작업 스레드에서 넣었는데
실제 작업은 모두 하나의 스레드에서 한개씩 이루어 지는 것을 알 수 있다.
working, entry index 0 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 1 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 2 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 3 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 4 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 5 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 6 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 7 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 8 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
working, entry index 9 thread <NSThread: 0x600000376ec0>{number = 7, name = (null)}
One thought on “Swift Thread 사용해 보기”
포스팅 잘 보고 갑니다~!