我已经开始做一个网络项目。但是在设置了std :: thread之后,while(true)循环将不会启动。
我要做的第一件事是设置正在侦听新客户端的std :: thread。在线程使用的函数中有一个while(true)循环,可以完美地工作。在初始化serverListener std :: thread之后的主线程中,再次是一个while(true)循环,尝试接收数据,但是该循环不会启动,除非当我在之前的while循环中放入std :: cout时for循环,但这会向我的控制台发送垃圾邮件。
变量和包含物
#include <SFML/Network.hpp>
#include <iostream>
#include <list>
#include <thread>
#define PORT 1337
unsigned int clientCounter = 0;
sf::TcpSocket clients[5];
sf::Packet packet;
std :: thread正在使用的函数:
void serverListener() {
sf::TcpListener listener;
listener.listen(PORT);
while (true) {
if (listener.accept(clients[clientCounter]) == sf::Socket::Status::Done) {
std::cout << "New client connected: "
<< clients[clientCounter].getRemoteAddress() << std::endl;
clientCounter++;
}
}
}
主线程:
int main()
{
std::thread serverListenerThread(&serverListener);
while(true) {
//std::cout << "Some message"; <----- when uncomment, the loop works?
for (int i = 0; i < clientCounter; i++) {
std::string message = "";
packet >> message;
if (clients[i].receive(packet) == sf::Socket::Status::Done) {
message += std::to_string(i);
std::cout << message << std::endl;
}
}
}
return 0;
}
答案 0 :(得分:1)
请稍等一下第一个线程所看到的内容。由于您在两个线程之间没有同步,因此编译器会假定它们不通信,因此在执行内部for循环时clientCounter
的值将永远不会改变。因此,循环将始终看到clientCounter=0
,因此循环不会运行。
unsigned int clientCounter = 0;
int main()
{
std::thread serverListenerThread(&serverListener);
while(true) {
for (int i = 0; i < clientCounter; i++) {
// Never executed, since clientCounter = 0
}
}
}
您应将clientCounter
设为std::atomic<unsigned int>
。这使编译器知道在线程之间同步变量。通常,您在线程之间共享的任何内容都应该是原子的,或者应该通过锁定互斥锁来进行保护。
增加睡眠可能会有所帮助,但只能靠运气;绝对没有理由应该继续工作。特别是,不需要在while循环迭代之间从内存中加载clientCounter
的值,因为编译器“知道”它永远不会写入主线程。因此,重新加载将是多余的。