我有一个服务器,它是以每个客户端一个线程的方式构建的。最近,我遇到了一个很难想出解决方案的问题,所以我想寻求帮助。
我的服务器有一个大厅,大厅里有很多房间(都是用户的),房间里有玩家。每个房间都有一个管理员,当管理员选择离开时 - 房间关闭,所有用户都应该返回大厅。
现在,我已经有了一个工作代码 - 但问题是,我不知道我应该如何让其他客户也退出房间。线程中运行的代码如下:
while(in_lobby)
{
//Receive a message
//Do stuff
//In certain cases change the Boolean to fit to the situation
//Send a comeback
}
while(in_room)
{
//Receive a message
//Do stuff
//In certain cases change the Boolean to fit to the situation
//Send a comeback
}
while(in_game)
{
//When a game started
//Not practical right now, though
}
bool 值从一个客户端的线程到另一个客户端没有问题(因为它们不完全是局部变量,它们是我可以通过处理管理员选择关闭房间的线程更改的几个条件) .
问题发生在条件确实改变时,而 while 循环应该在下一次迭代之前退出。为什么会发生?因为在迭代开始时有一个 recv()
调用,它等待客户端的消息。
现在,条件好了,一切都好了,但是循环不会继续(所以它不会到达下一次迭代 - 看条件是否为假)直到服务器收到来自客户端的某个消息(这不应该,因为关闭房间不依赖于普通用户 - 用户只接收和警告,这也是通过管理员的线程发送的,关于房间被关闭)。
因此我的问题是:
我怎样才能做我想做的事?我怎样才能让这些用户跳出循环,返回大厅(管理员这样做没有问题,因为他的线程是做所有事情的线程,他成功返回大厅)而不改变整个从每个客户端线程的方式架构?
最佳答案
"Because in the beginning of the iteration there's a recv() call, which awaits the client's messages."
可能您不想阻塞 recv()
在这一点上调用第一名。
有 select()
来自 Windows Socket API 的函数,您可以使用它来观察多个套接字文件描述符的状态变化。
基本上你会有一个线程运行一个循环,并轮询 select()
的返回值。称呼。不要用紧密的循环占用 CPU,应该指定一个合理的超时值,但零超时也是可能的,并且也只轮询可用状态。
如果返回值表明观察到的套接字之一(select() > 0
)有一些可用的操作,您可以检查观察到的套接字文件描述符(如果它们是使用
FD_ISSET(s, *set)
宏。
关于c++ - 如何中断其他 std::threads C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30081889/