我对TCP / IP(多线程)感到好奇,一个程序确实改变了var,另一个程序可以在循环中认识var的变化吗?
我很好奇的原因是我正在制作一个简单的游戏,并且它有一个大厅等待其他玩家进来,但是在同一个客户端。我认为没有办法等待其他球员。
我做了while(ready = 0)
循环,当一个客户端进入房间时更改var(ready)= 1所以我将它发送到服务器,但是roommaker客户端无法打破循环.... / p>
这是我的代码:
while(1){
recv(socket,a,sizeof(a),0);
ready = atoi(ready);
if(ready = 1){
break;
}
}
为什么会这样?
答案 0 :(得分:0)
问题(如果我理解正确的话)是询问,当线程A将变量设置为新值时,如果线程B将"请参阅"变量的值变化。
简短的回答可能是,但是你不应该依赖它,因为让线程共享对这样的值的读/写访问权限是不确定的行为,并且它通常不会表现出来你想要它的方式"。如果要在线程之间共享变量,则需要使用互斥锁保护对该值的访问(读取和写入),或者(在C ++中)使用std :: atomic变量而不是常规int / bool / etc数据类型。
共享一个普通的旧变量并不能可靠地运行的原因是因为计算机现在非常复杂 - 编译器会发挥很多巧妙的技巧来使你的程序的可执行代码更高效,并且现代CPU也会在运行时发挥更加巧妙的技巧,使事情更快。但是,编译器和CPU都不知道"您的ready
变量旨在跨线程共享;实际上,为了执行优化,他们都会假设它不会成功 - 比如在CPU寄存器中缓存变量的值,这样线程就不必重新读取它RAM每次都通过循环。当优化发生时,线程A可以更改ready
的值,但是该更改可能会或可能不会及时将其发送到RAM,即使这样做,线程B可能会也可能不会注意到更改在RAM中(即如果它已经在寄存器中缓存了该值,它就赢了)。
所以,建议是:不要像这样分享一个简单的变量 - 它是一个竞争条件,你的程序很可能按照你的预期方式工作。对于多线程程序,您必须非常小心地使用互斥锁或(在C ++中)使用std :: atomic类型(它告诉编译器变量旨在跨线程共享,以便它可以采用)来共享共享变量额外的步骤,以确保在读或写时正确的事情发生。)