【问题标题】:Thread is blocking whole program线程阻塞了整个程序
【发布时间】:2012-11-06 22:56:33
【问题描述】:

我正在尝试制作一个多客户端服务器。我有这个线程:

void client_thread(int new_socket)
{
    int size;
    char inbuffer[BUF];

    do
    {
        cout << "Waiting for messages: " << endl;
        size = recv(new_socket, inbuffer, BUF, 0);
    } while (true);
}

还有这个主要程序:

int main()
{
    while (true)
    {
        //waiting for clients
        cout << "Waiting for connections..." << endl;
        new_socket = accept ( create_socket, (struct sockaddr *) &cliaddress, &addrlen );

        //new client connected
        if (new_socket > 0)
        {
            //start thread
            thread(client_thread, new_socket).join();
        }
    }
    return 0;
}

当第一个客户端连接时,线程启动并且服务器正在等待来自他的消息。但是服务器不再等待新的客户端。我不知道为什么。是因为线程函数内部的无限 do-while 循环吗?如果线程包含无限循环,它们会阻塞您的整个程序,那么线程的意义何在?

【问题讨论】:

    标签: c++ multithreading block


    【解决方案1】:

    主程序阻塞,因为它等待线程完成:join()

    如果您不想阻止,请不要join()您的client_thread。

    此异常可能来自您的匿名线程对象的破坏。当您离开if() 的范围时,此范围内的所有对象都将被销毁。从http://en.cppreference.com/w/cpp/thread/thread/~thread 可以看到,析构函数调用terminate()。为避免这种情况,您可以致电detach()。所以你必须说thread(client_thread, new_socket).detach();,而不是thread(client_thread, new_socket).join();

    【讨论】:

    • 如果我删除join(),一旦客户端连接到以下消息,程序就会崩溃:terminate called without an active exception
    • thread() 来自哪个库?那是你写的函数吗?很难说为什么你会得到例外。 join() 肯定会导致阻塞,并且掩盖了导致崩溃的问题。
    • 不,它不是自定义函数。它来自std::thread (c++0x)。我也考虑过这样编译:g++ -std=c++0x main.cpp -lpthread
    • 非常感谢伙计! .detach() 而不是 .join() 成功了。但是为什么在thread(...)之后还要调用析构函数呢?
    • 您对thread() 的调用会创建一个匿名对象。当您离开if (...) {...}末尾的范围时,此对象将被破坏。
    【解决方案2】:

    您应该创建一个线程并保留对它的引用,直到您加入它。在您的代码中,线程对象在创建后立即被释放,因此如果不立即调用 join 则会出现错误。

    要正确实现这一点,最好的方法是在堆上分配对象,使用运算符new 并将指针存储在某个位置的列表中。当线程完成时,它可能会从列表中删除自己(不要忘记“互斥”它),或者您可以让另一个专用线程这样做:也许您可以简单地让您的主线程在退出之前加入所有其他线程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 1970-01-01
      • 2017-12-24
      • 2019-09-01
      相关资源
      最近更新 更多