简体   繁体   English

为什么在std :: thread启动后我的while循环不启动?

[英]Why isn't my while-loop starting after the std::thread is started?

i've started doing a project with networking. 我已经开始做一个网络项目。 But after setting up a the std::thread, the while(true)-loop wont start. 但是在设置了std :: thread之后,while(true)循环将不会启动。

The first thing i have done is setting up the std::thread which is listening for new clients. 我要做的第一件事是设置正在侦听新客户端的std :: thread。 In the function which the thread is using is a while(true)-loop, which perfectly works. 在线程使用的函数中有一个while(true)循环,可以完美地工作。 In in the main thread after initializing the serverListener std::thread, is again a while(true)-loop which tries to recieve data, but this loop wont start, except when I put a std::cout in the while-loop before the for-loop, but this spams my console. 在初始化serverListener std :: thread之后的主线程中,再次是一个while(true)循环,尝试接收数据,但是该循环不会启动,除非当我在之前的while循环中放入std :: cout时for循环,但这在我的控制台中发了垃圾。

Variables and inclusions: 变量和包含:

#include <SFML/Network.hpp>
#include <iostream>
#include <list>
#include <thread>

#define PORT 1337

unsigned int clientCounter = 0;

sf::TcpSocket clients[5];
sf::Packet packet;

The function which the std::thread is using: 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++;
        }
    }
}

Main thread: 主线程:

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;
}

Think for a moment about what the first thread sees. 想一想第一个线程看到的内容。 Since you have no syncronisation between the two threads, the compiler assumes they don't communicate and so the value of clientCounter will never change while the inner for loop is being executed. 由于两个线程之间没有同步,因此编译器会假定它们不通信,因此在执行内部for循环时, clientCounter的值将永远不会改变。 Thus the loop will always see clientCounter=0 and so the loop doesn't run. 因此,循环将始终看到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
        }
    }
}

You should make clientCounter an std::atomic<unsigned int> . 您应该将clientCounter std::atomic<unsigned int> This lets the compiler know to synchronise the variable between threads. 这使编译器知道在线程之间同步变量。 In general, anything that you share between threads should either be atomic or should be protected by locking a mutex. 通常,线程之间共享的任何内容都应该是原子的,或者应该通过锁定互斥锁来进行保护。

Adding a sleep may help but only by pure luck; 增加睡眠可能有所帮助,但只能靠运气。 there is absolutely no reason why it should continue to work. 绝对没有理由应该继续工作。 In particular, there is no requirement to load the value of clientCounter from memory between while loop iterations, since the compiler 'knows' it is never written to in the main thread. 特别是,不需要在while循环迭代之间从内存中加载clientCounter的值,因为编译器“知道”它永远不会写入主线程。 Thus, reloading it would be redundant. 因此,重新加载将是多余的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM