C++ winsockets 线程问题

标签 c++ multithreading

我制作了一个非常简单的 C++ 套接字服务器。我试图在每次新客户端连接时生成一个线程(因此可以并行读取)。

void Server::start(void){
    for(;;){ 
        Logger::Log("Now accepting clients");
        int client;
        struct sockaddr_in client_addr;
        size_t addr_size = sizeof(client_addr);
        client = accept(this->m_socket, (sockaddr*)&client_addr, 0);
        if(client != SOCKET_ERROR){
            Logger::Log("New client connected!");
            StateObject client_object(client, this);
            this->clients.push_back(&client_object);

            std::stringstream stream;
            stream<<this->clients.size()<<" clients online";
            Logger::Log(const_cast<char*>(stream.str().c_str()));
            std::thread c_thread(std::bind(&StateObject::read, std::ref(client_object)));
            //c_thread.join(); //if I join the child, new clients won't be accepted until the previous thread exits
        }
    }
}

客户端类中的读取方法:

void StateObject::read(){
    Logger::Log("Now reading");
    for(;;){
        int bytesReceived = recv(this->socket, buffer, 255, 0);
        if(bytesReceived > 0){
            Logger::Log(const_cast<char*>(std::string("Received: " + std::string(buffer).substr(0, bytesReceived)).c_str()));
        }else if(bytesReceived == 0){
            Logger::Log("Client gracefully disconnected");
            break;
        }else{
            Logger::Log("Could not receive data from remote host");
            break;
        }
    }
    Server * server = reinterpret_cast<Server*>(parent);
    server->removeClient(this);
}

目前客户端连接后抛出异常: Screenshot

为什么以及何时触发中止? 请注意,当子线程尚未加入主线程时会发生这种情况。在另一种情况下,“流程”按预期同步进行(当前客户端线程必须退出,以便循环可以继续接受下一个客户端)。

注意事项:

  • 因为我依赖于 Windows,所以我无法 fork 子任务 - 我也不喜欢 Cygwin。异步 win32 方法似乎会使事情复杂化,这就是我避免使用它们的原因。
  • C++ std::thread reference
  • 已通过 Telnet 完成测试

最佳答案

您需要在线程超出范围之前分离线程或加入它。否则 std::thread 在其析构函数中调用 std::terminate。

http://www.cplusplus.com/reference/thread/thread/~thread/

关于C++ winsockets 线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22116467/

相关文章:

java - 线程队列使用什么设计模式

.net - CLI库代码Thread Safe中的Comparer类是否安全?

java - `thenRunAsync(...)` 和 `CompletableFuture.runAsync(() -> { ... });` 有关联吗?

python - 高效地生成一个字符串所有可能子串的列表

java - volatile 变量和其他变量

java - 线程的Join方法

c++ - 自动更新 QDateTimeEdit 以显示当前系统日期和时间

c++ 递归加法,4*x

java - JNI 检测到应用程序错误 : use of deleted weak global reference

c++ - 覆盖文件中的字节而不清除它