2010-05-16 2 views
2

내 응용 프로그램에 2 개의 스레드, 게임 업데이트 스레드 및 렌더링/IO/주 스레드가 있습니다. 내 업데이트 스레드가 게임 상태를 업데이트하고 렌더링 스레드가 게임 상태 모델의 업데이트 된 값과 객체 (gameEngine) 내부에 저장된 몇 가지 다른 변수를 기반으로 장면을 렌더링합니다. 게임 스레드가 여전히 문제가있는 업데이트하는 동안 스레드 렌더링내 @synchronized 블록에 어떤 문제가 있습니까?

이 실행됩니다, 그래서 해결책은 다음과 같이 @synchronized 사용하는 나에게 나타나

 @synchronized(gameEngine) 
     { 
      [gameEngine update]; 

      nextUpdate = now + GAME_UPDATE_INTERVAL; 

      gameEngine.lastGameUpdateInterval = now - lastUpdate; 
      gameEngine.lastGameUpdateTime = now; 
      lastUpdate = now; 
     } 

을하지만, 스레드가 여전히 액세스 렌더링 -update와 블록의 마지막 3 행 사이의 gameEngine 객체 왜 이런거야?

+0

렌더 스레드에서 실행해야하는 코드도 함께 표시하십시오. 동일한 gameEngine 객체의 @synchronize 블록 안에 있습니까? – Ken

답변

10

@synchronized 다른 스레드가 gameEngine에 액세스하는 것을 차단하지 않습니다. 동일한 객체를 가진 다른 @synchronized을 차단합니다. 즉

// thread A: 
@synchronized(a) { 
    do_A(a); 
} 
... 
// thread B: 
do_B(a); 

do_Ado_B 함께 일어날 수있는 의미하지만,

// thread A: 
@synchronized(a) { 
    do_A(a); 
} 
... 
// thread B: 
@syncrhonized(a) { 
    do_B(a); 
} 

do_Ado_B 항상 순차적으로 실행됩니다.

+0

이것은 정확하게 내가하고 있었던 일이며 그것을 해결하기 위해해야 ​​할 일입니다. – Morrowless

+0

이것은 많은 도움이 된 훌륭한 답변입니다. 감사합니다. – krafter

0

GameEngine을 잠그면 안됩니다. @KennyTM은 질문에 대한 정답이라고 생각하지만 게임 엔진이나 렌더러 만 실행하면 주어진 시간에 실행할 수 있습니다. , 본질적으로 단일 스레드로 만듭니다. 당신이 gameEngine의 바르 될 수있다 불변 상태 개체를 사용하는 일을해야하지만, 렌더링 기능에 당신이 상태를 사용할 수 있도록

State *state = [[gameEngine state] retain]; 

다음과 같은 상태를 잡아 비 원자을해야한다, 완료되면 풀어 놓습니다. gameEngine은 업데이트를 수행 할 때 렌더러가 사용할 수있는 상태 ivar의 데이터를 변경해서는 안되지만 복사본을 만들 수 있습니다. 상태를 설정하려면, 그것을해야

State *oldState = state; 
state = newState; //newState should have a retainCount of 1 
[oldState release]; 

당신이 나쁜 일에 이르는 단지 해제 된 oldstate가를 얻을 수 있습니다 newState에 다음 렌더러를 상태를 설정하기 전에 oldstate가를 놓으면 때문이다.

+0

-1, 할당되지 않은 개체에 대한 참조가있는 렌더러로 이어질 수있는 경쟁 조건이 있습니다. '[[gameEngine state] retain]'은 원자 적이지 않습니다. 렌더러가'gameEngine state'로부터 돌아온 후에 렌더러가 인터럽트되면서 retain을 보내기 전에, 렌더러가 retain을 스케쥴하기 전에 게임 엔진이'[oldState release]'를 포함하는 상태를 완전히 갱신 할 수 있다면, 그 객체는 할당 해제 될 수 있습니다. – JeremyP

+0

그는 당신이 원하는 것을 달성하는 안전한 방법은'-state'를 원자 속성으로 만드는 것입니다. 이것은 동기화 된 코드의 작은 부분을 이끌지 만 단일 스레드 부분은 ivar에 retain 및 autorelease를 보내는 데 걸리는 시간으로 효과적으로 제한됩니다. – JeremyP

+0

상태가 원자 상태 인 경우에도 - [gameEngine state]는 유효한 참조를 반환하지만 retain이 호출되기 전에 사라질 수 있음을 의미합니다. 그것이 옳다는 말은 아닙니다. 멀리에서, 내 경쟁 조건을 불러 주셔서 감사합니다.하지만 상태가 설정되어 있기 때문에 - [gameEngine state]는 항상 하나 이상의 보유 수를 보장합니다. –

관련 문제