2

我的应用程序中有 2 个线程,一个游戏更新线程和渲染/IO/主线程。我的更新线程更新游戏状态,渲染线程根据游戏状态模型的更新值和存储在对象 (gameEngine) 中的一些其他变量来渲染场景。

渲染线程在游戏线程仍在更新时执行,这是一个问题,所以在我看来解决方案是像这样使用@synchronized:

        @synchronized(gameEngine)
        {
            [gameEngine update];

            nextUpdate = now + GAME_UPDATE_INTERVAL;

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

-update但是渲染线程仍然在块的最后 3 行之间访问 gameEngine 对象。为什么是这样?

4

2 回答 2

10

@synchronized不会阻止其他线程访问gameEngine. @synchronized它只是用相同的对象阻止其他人。这意味着在

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

do_A并且do_B可以同时发生,但在

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

do_A并将do_B始终按顺序执行。

于 2010-05-16T19:08:46.330 回答
0

你不应该锁定游戏引擎——@KennyTM 解释了我认为对你的问题的正确答案,但是实施它只会导致游戏引擎或渲染器在给定时间能够执行,本质上是单线程。您应该做的是使用不可变状态对象,它可能是 gameEngine 的 ivar,但应该是 nonatomic ,渲染函数中您可以像这样获取状态

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

然后使用状态,完成后释放它。当游戏引擎执行更新时,它不应该改变其状态 ivar 中的数据,这可能正在被渲染器使用,但可能会复制它。要设置状态,它应该

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

因为如果你在将 state 设置为 newState 之前释放 oldState,那么渲染器可能会得到 oldState,它刚刚被释放,导致坏事。

于 2010-05-16T19:23:51.880 回答