다음과 같이 직렬 대기열을 만들었습니다.
dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
dispatch_async
이처럼 호출 의 차이점은 무엇입니까
dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
dispatch_async(_serialQueue, ^{ /* TASK 2 */ });
그리고 dispatch_sync
이 일련 큐에 다음과 같이이라고?
dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });
내 이해는 어떤 디스패치 방법을 사용하든 TASK 1
전에 실행되고 완료된다는 것입니다 TASK 2
.
답변
예. 직렬 대기열을 사용하면 작업의 직렬 실행이 보장됩니다. 유일한 차이점은 dispatch_sync
블록이 완료된 후에 만 리턴하는 반면 dispatch_async
큐에 추가 된 후에 리턴하면 완료되지 않을 수 있다는 것입니다.
이 코드
dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");
그것은 인쇄 할 수 있습니다 2413
또는 2143
또는 1234
하지만 1
항상 전3
이 코드
dispatch_sync(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_sync(_serialQueue, ^{ printf("3"); });
printf("4");
항상 인쇄 1234
참고 : 첫 번째 코드의 경우 인쇄 되지 않습니다1324
. 가 실행 된 후에printf("3")
전달 되기 때문 입니다 . 작업 은 발송 된 후에 만 실행할 수 있습니다 . printf("2")
작업 실행 시간은 변경되지 않습니다. 이 코드는 항상 인쇄12
dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); });
dispatch_async(_serialQueue, ^{ printf("2"); });
일어날 수있는 일은
- 스레드 1 : 시간이 많이 걸리는 작업 (작업 1)을 serial queue로 dispatch_async
- 스레드 2 : 태스크 1 시작
- 스레드 1 : 다른 작업 (작업 2)을 직렬 대기열로 dispatch_async
- 스레드 2 : 작업 1 완료 작업 2 시작
- 스레드 2 : 작업 2 완료
그리고 당신은 항상 볼 12
답변
차이 dispatch_sync
와는 dispatch_async
간단하다.
두 예제 모두에서 TASK 1
항상 TASK 2
전달되기 때문에 항상 전에 실행 됩니다.
dispatch_sync
그러나이 예 에서는 TASK 2
after TASK 1
을 디스패치 하고 실행할 때까지 디스패치하지 않습니다 . 이것을 “차단”이라고 합니다. 코드는 작업이 실행될 때까지 대기합니다 (또는 “차단”).
이 dispatch_async
예제에서 코드는 실행이 완료되기를 기다리지 않습니다. 두 블록 모두 대기열로 전달되고 대기열에 추가되며 나머지 코드는 해당 스레드에서 계속 실행됩니다. 그런 다음 (언제든지 큐에 디스패치 된 내용에 따라) 어느 시점에서 Task 1
실행 된 다음 Task 2
실행됩니다.
답변
모두 메인 큐와 관련이 있습니다. 순열은 4 개입니다.
i) 시리얼 대기열, 디스패치 비동기 : 여기서 작업이 차례로 실행되지만 주 스레드 (UI에 미치는 영향)는 반환을 기다리지 않습니다.
ii) 시리얼 큐, 디스패치 동기화 : 여기서 작업이 차례대로 실행되지만 메인 스레드 (UI에 미치는 영향)가 지연됩니다
iii) 동시 대기열, 디스패치 비동기 : 여기서 작업이 병렬로 실행되고 주 스레드 (UI에 영향)가 반환을 기다리지 않고 부드럽게됩니다.
iv) 동시 대기열, 디스패치 동기화 : 여기서 작업이 병렬로 실행되지만 주 스레드 (UI에 미치는 영향)가 지연됩니다
동시 또는 직렬 대기열의 선택은 다음 작업에 대한 이전 작업의 출력이 필요한지 여부에 따라 다릅니다. 이전 작업에 의존하는 경우 직렬 대기열을 채택하고 동시 대기열을 사용하십시오.
그리고 마지막으로 이것은 우리가 사업을 마쳤을 때 주 스레드로 다시 침투하는 방법입니다.
DispatchQueue.main.async {
// Do something here
}