2017-04-07 3 views
0

동일한 스레드에서 코드 블록을 반복적으로 액세스하지 못하게하려면 어떻게합니까? 완료가 호출되기 전에,단일 스레드에서 여러 작업 동기화

func sendAnalytics() { 
    // some synchronous work 

    asyncTask() { _ in 
     completion() 
    } 
} 

내가 "// 어떤 동기 작업"에 액세스 어떤 스레드를 방지하려면 : 가정하자

, 나는 다음 코드가 있습니다.

objc_sync_enter(self) 
objc_sync_exit(self) 

여러 스레드에서이 코드에 액세스하는 것만 방지하고 단일 스레드에서이 코드에 액세스하지 못하게하는 것처럼 보입니다. 사용자 지정 솔루션을 사용하지 않고이 작업을 올바르게 수행 할 수 있습니까?

반복적으로 액세스하는 것은 한 스레드에서이 sendAnalytics를 여러 번 호출하는 것입니다. 다음과 같이 for가 있다고 가정합니다.

for i in 0...10 { 
    sendAnalytics() 
} 

sendAnalytics가 호출 될 때마다 다음 호출이 완료 될 때까지 기다리지 않습니다. 완료가 시작되기 전에 다음 호출을 대기시키는 방법이 있습니까? 또는 사고의 전체적인 방식이 잘못되었습니다. 나는이 문제를 더 높은 차원에서 해결해야합니다. 다음은

let semaphore = DispatchSemaphore(value:1) 

func sendAnalytics() { 
    self.semaphore.wait() 
    // some synchronous work 

    asyncTask() { _ in 
     completion() 
     self.semaphore.signal() 
    } 
} 

첫 AsyncTask를이 완료 될 때까지 sendAnalytics에 대한 두 번째 호출이 차단됩니다를 시작하기 전에

+0

그것은 당신이 처음이 완료 될 때까지 두 번째 발신자를 차단하거나 두 번째 호출이 차단 – Paulw11

+0

생략할지 여부 따라 달라집니다 이러한 위험을 제거하기 위해 자신의 시리얼 파견 큐 상에 sendAnalytics 전화를 파견 아마 안전 두 번째 호출자 –

+0

그런 다음 초기 카운트가 0 인 dispatch_semaphore를 사용하십시오. 그러나 주 큐를 차단하는 데주의하십시오. – Paulw11

답변

2

당신은 하나의 호출이 완료 될 수 있도록하기 위해 DispatchSemaphore 사용할 수 있습니다. 메인 대기열을 차단하지 않도록주의해야합니다. 그러면 앱이 응답하지 않게됩니다.

let semaphore = DispatchSemaphore(value:1) 
let analyticsQueue = DispatchQueue(label:"analyticsQueue") 

func sendAnalytics() { 
    analyticsQueue.async { 
     self.semaphore.wait() 
     // some synchronous work 

     asyncTask() { _ in 
      completion() 
      self.semaphore.signal() 
     } 
    } 
} 
+0

전혀 호출하지 않습니다. 하지만 작동합니다 세마포어 = DispatchSemaphore (값 : 1) –

+0

미안 해요, 제 실수. 1이 맞다. – Paulw11

관련 문제