twe*_*ypi 2 c# mono multithreading xamarin.ios
这是(大致)我所拥有的:
class A
{
public bool IsInUpdate = false;
public void Update()
{
IsInUpdate = true;
//(...do stuff...)
IsInUpdate = false;
}
}
class B
{
A a_inst;
System.Threading.Thread physicsThread = null;
void Draw()
{
physicsThread = new System.Threading.Thread(a_inst.Update);
physicsThread.Start();
}
void Update()
{
while(physicsThread.IsAlive)
{
// Right here there can be cases where physicsThread.IsAlive is true but IsInUpdate is false, how does that happen?
}
(...do stuff...)
}
}
Run Code Online (Sandbox Code Playgroud)
问题在代码的注释中.基本上物理线程实例说它还活着,但它调用的函数显然已经完成调用(可以看出bool设置为false).
任何想法为什么会这样?我想要做的就是确保在类A的线程更新函数执行之前,B类中的更新函数不会执行...
既然IsInUpdate只是一个公共领域(而非volatile那个领域),就无法保证你看到的东西; 关于你所看到的内容的正常合理规则仅适用于单个线程,并且你没有保护任何这些数据.还有周围的边缘的情况下启动的条件,但我个人会使用或者lock(如果你需要等待它完成),或者也许Interlocked如果你只需要知道,如果它是积极的.
例如:
class A
{
private readonly object syncLock = new object();
public object SyncLock { get { return syncLock; } }
public void Update()
{
lock(SyncLock)
{
//(...do stuff...)
}
}
}
Run Code Online (Sandbox Code Playgroud)
和
void Update()
{
lock(a_inst.SyncLock)
{
(...do stuff...)
}
}
Run Code Online (Sandbox Code Playgroud)
通过以上,可以保证只有一个线程将有权随时锁定,所以,如果你能"做的东西",你知道,这是不是也正在运行的其他更新().如果你需要等待,还有Wait()/ Pulse()方法来防止锁,或者你可以使用ManualResetEvent/ 等门AutoResetEvent.
这样的事情lock也确保了线程之间正确的内存障碍,因此您可以看到正确的数据.