1

원칙적으로 일련 번호 DispatchQueue은 제출 된 작업을 하나씩 실행합니다. 그러나 컨텍스트 스위치가 한 작업에서 트리거되는 경우 (예 : sleep)? 큐가 즉시 다음 작업을 실행합니까, 아니면 현재 작업이 완료 될 때까지 대기합니까? 이 코드에 대한컨텍스트 스위치가 직렬 DispatchQueue에서 트리거되는 경우 어떻게됩니까?

:

q.async { 
    print("IN 1") 
    var i = 1 
    while i < 10 { 
    Thread.sleep(forTimeInterval: 0.1) 
    i += 1 
    } 
    print("OUT of 1") 
} 

q.async { 
    print("IN 2") 
} 

은 결과입니다

// IN 1 -> OUT of 1 -> IN 2 ? 
// or IN 1 -> IN 2 -> OUT of 1 ? 

내가 놀이터에서 코드를 실행하려하지만 sleep 보인다 (그리고 Thread.sleep)이 놀이터에서 작동하지 않습니다.

답변

0

원칙적으로 직렬 DispatchQueue는 제출 된 작업을 차례로 실행합니다. 하지만 컨텍스트 스위치가 한 작업 (예 : 잠자기)에서 트리거되면 어떻게됩니까? 큐가 즉시 다음 작업을 실행합니까, 아니면 현재 작업이 완료 될 때까지 대기합니까?

직렬 대기열은 작업이 순차적으로 제출되기 때문에 "직렬"이 아니며 (사실 대부분의 작업은 일반적으로 병렬 대기열에서도 수행되기 때문에), 작업이 하나씩 완료된다는 보장이 있기 때문에 그들이 제출 된 순서.

Thread.sleep은 놀이터에서 정상적으로 작동하지만 놀이터에서 실행이 일찍 종료됩니다. 제어 흐름이 페이지의 끝에 도달하면 놀이터의 실행이 종료됩니다. 따라서 이러한 비동기 작업은 제어 흐름이 페이지의 끝에 도달하기 전에 실행되는 경우에만 완료됩니다. 이는 거의 불가능합니다.

import PlaygroundSupport 
PlaygroundPage.current.needsIndefiniteExecution = true 
+0

실제로. PlaygroundSupport에 대한 팁 주셔서 감사합니다! – NeoWang

4

직렬 큐는 이전이 완료 될 때까지 다음 블록 실행을 시작하지 않습니다

사용, (수동 종료 될 때까지) 무기한 실행 놀이터를 유지합니다. 문맥 전환은 이것에 영향을 미치지 않습니다. 직렬 대기열에 제출 된 블록에서 sleep으로 전화하면 절전 모드가 종료되고 블록이 실행을 재개 할 때까지 대기열을 차단합니다. 결과는 IN 1 -> OUT of 1 -> IN 2입니다.

대기열에 제출 된 블록에서 일반적으로 차단 대상 (예 : sleep)을 원하지 않습니다. 전체 스레드를 차단하므로 libdispatch를 다른 작업에 사용할 수 없기 때문입니다. libdispatch는 작업을 계속하기 위해 필요에 따라 새로운 스레드를 회전 시키지만, 생성 할 새 스레드의 수에는 제한이 있습니다.