Thread.joinable返回true,即使线程尚未完成执行

时间:2018-03-12 21:22:31

标签: c++ multithreading thread-safety sfml

std::mutex MTX;
bool ExitThread = false;

//This function is running in a separate thread 
//for constantly trying to connect to a server in a non blocking manner
void ClientConnectingLoop(sf::TcpSocket* client, std::string ipAddress, 
unsigned short port)
{
    std::cout << "Start" << std::endl;
    MTX.lock();
    std::cout << "Start2" << std::endl;
    while(client->connect(ipAddress, port) != sf::Socket::Status::Done && 
    !ExitThread)
    {

    }

    std::cout << "Done" << std::endl;
    MTX.unlock();
}


int main()
{
    //Code for setting ipaddress and port is abstracted.
    std::string ipAddress;
    unsigned short port;

    //Setup socket
    sf::TcpSocket clientSocket;
    clientSocket.setBlocking(false);

    //Connect to server
    std::thread ClientConnectThread(ClientConnectingLoop, &clientSocket, ipAddress, port);
    std::cout << "Connecting to server......" << std::endl;


    //Wait until it finishes executing, code inside this loop is abstracted
    while(!ClientConnectThread.joinable())
    { 
    }

    //The thread is finished executing.
    if(ClientConnectThread.joinable())
    {
        std::cout << "Joinable returned true" << std::endl;
        ClientConnectThread.join();
    }

    //........
}

问题是,尽管线程中的循环仍在运行,但线程返回joinable(true)。

这意味着控制台输出“正在连接服务器......”=&gt; “开始”=&gt; “Start2”=&gt; “Joinable返回true”但“完成”应该在“Start2”之后打印,除非我误解了可连接函数

我仍然是c ++和SFML的新手,请在指出任何错误时要善意。

1 个答案:

答案 0 :(得分:2)

直接从cppreference.com

报价
  

的std ::螺纹::可连接

     

检查线程对象是否标识了活动的执行线程。具体来说,如果get_id()!= std :: thread :: id(),则返回true。因此默认构造的线程不可连接。   已完成执行代码但尚未加入的线程仍被视为活动执行线程,因此可以连接。

基于此,可连接线程的想法是不同的。线程始终是可连接的,除非已经默认构造并且尚未分配给要运行的函数/方法,或者您已经在其上调用了thread.join()方法。

对于当前问题的一个相当简单的解决方案是使用一些多线程感知锁定构造,如std::atomicvoid futures来传达Effective Modern C++ book of Scott Meyers中建议的结果