2014-11-15 1 views
1

dispatch_queue_t에 대한 액세스를 제어하는 ​​세마포가 있다고 가정합니다. 디스패치 큐에서 블록을 예약하기 전에 세마포 (dispatch_semaphore_wait)를 기다립니다.세마포어로 우선 제어

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER) 
dispatch_async(queue){ //do work ; dispatch_semaphore_signal(semaphore); } 

여러 개의 다른 위치에서 대기하는 것으로 가정 해 봅니다. 일부 "저작물"은 다른 "저작물"보다 우선 순위가 높습니다.

"작업"중 다음에 예약 할 작업을 제어하는 ​​방법이 있습니까?

추가 정보 : "작업"이 여러 개의 블록이있는 자체 대기열로 구성되어 있기 때문에 세마포없이 연속 대기열을 사용하는 것은 나를위한 옵션이 아닙니다. 모든 작업 대기열이 실행되어야하며 그렇지 않은 경우가 있습니다. 작업 대기열을 동시에 실행할 수는 없습니다. 우선 순위 제어를 제외하고는이 모든 것이 정상적으로 작동합니다.

편집 : 좋아

(제레미에 대한 응답, 의견에서 이동), 당신은 어떤 프린터와 같은 장치/파일/있다고 가정합니다. 인쇄 작업은 트랜잭션에서 그룹화 된 여러 함수 호출/블록 (인쇄 머리글, 그림 인쇄, 텍스트 인쇄 등)으로 구성됩니다. 이 블록을 직렬 대기열에 넣으십시오. 트랜잭션 당 하나의 큐.

그러나 여러 개의 인쇄 작업/트랜잭션을 가질 수 있습니다. 다른 인쇄 작업/트랜잭션의 블록은 혼합 할 수 없습니다. 그렇다면 트랜잭션 큐가 모든 작업을 실행하고 다른 큐가 완료되기 전에 트랜잭션 큐가 시작되지 않도록하려면 어떻게해야합니까? (나는 이것을 인쇄하지 않고 그냥 예제로 사용한다).

세마포어는 유한 리소스 사용을 규제하는 데 사용됩니다. https://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html Concurrency Programming Guide

내가 알아 내려고 노력하고 다음 단계는 다른 전에 하나의 트랜잭션을 실행하는 방법입니다.

+0

하나의 트랜잭션을 다른 트랜잭션보다 먼저 실행하는 것이 정확히 직렬 대기열을위한 것입니다. 각 트랜잭션을 큐에서 차단해야합니다. 우선 순위 반전으로 쉽게 이어질 수 있으므로 세마포어 사용을 버리십시오. –

+0

좋아요, 우선 순위 반전과 재검토를하겠습니다. – user965972

답변

1

여기 API를 오용하고 있습니다. 대기열을 디스패치하도록 예약 된 것을 제어하기 위해 세마포어를 사용하지 않아야합니다.

대기열에서 블록의 실행을 직렬화하려면 동시 대기열이 아닌 직렬 대기열을 사용하십시오.

대기열에 넣는 다른 블록의 우선 순위가 다른 경우 OS X 10.10 및 iOS 8.0에 추가 된 QOS 메커니즘을 사용하여 다른 우선 순위를 표현해야합니다. 구형 시스템에서 실행해야하는 경우 적절한 우선 순위의 전역 동시 대기열을 사용할 수 있습니다. 그 이상으로 오래된 시스템에는 많은 통제가 없습니다.

또한 세마포어는 시스템이 세마포어를 신호 할 사람을 결정할 방법이 없으므로 우선 순위 상속에 대해 본질적으로 작동하므로 더 긴 우선 순위의 스레드가 오랜 시간 동안 차단되는 상황에서 쉽게 끝날 수 있습니다 우선 순위가 낮은 쓰레드가 세마포어를 알리는 신호. 이를 우선 순위 반전이라고합니다.

+0

각 트랜잭션은 큐의 단일 블록이어야합니다. 대기 행렬의 단일 블록에서 트랜잭션의 조각 인 모든 작은 블록을 실행할 수 있습니다. –

+0

그런 다음 리소스와 관련이없는 많은 작업을 수행중인 경우 큐를 차단합니다.데이터베이스에서 1M 행을 추출하고, 물건을 계산 한 다음 (긴 작업) 데이터베이스에 응답을 반환해야한다고 가정합니다. 백그라운드에서 숫자를 처리하는 동안 데이터베이스 대기열을 차단하고 싶지는 않습니다. – user965972

+1

그런 다음 DB 액세스 대기열에서 처리하지 않아야합니다. db 대기열의 db에서 데이터를 가져온 다음 백그라운드 대기열에서 처리를 실행 한 다음 결과를 db 대기열에 추가하십시오. 읽기/쓰기 액세스를 시도한다고 가정 할 때, 쓰기를위한 장벽을 사용하여 동시 대기열을 사용해야합니다. –