C++ 对象和线程

标签 c++ multithreading object vector

我正在做一个简单的服务器应用程序,您可以在其中有多个连接,每个连接都是一个线程。这是我希望它看起来像的示例(它不起作用),有一个线程集合,其中每个线程实例化类连接的一个对象:

class connection{};

class server{
std::vector<std::thread> active_connections;
public:
    void listen() {active_connections.push_back(std::thread(connection));}
};

我一直在寻找解决方案,但我能找到的最好的解决方案是一些成员函数线程。当我测试它时,解决方案变得非常错误,例如:

class connection{};

class server{
std::vector<std::thread> active_connections;
public:
    void new_connection() { ... }
    void listen() { 
        active_connections.push_back(std::thread(&server::new_connection,this)); }
    };

消息是:错误:使用已删除的函数‘std::thread::thread(const std::thread&)。 这是否意味着 std::thread 类想要复制服务器类??我不太了解 C++,所以请不要喷,我只是问问。

谢谢!

编辑:

这是发生这种情况的地方:

void server::do_listen()
{   
    int addr_size = sizeof(sockaddr_in);
    sockaddr_in client_sock;
    connection_info cn_info;

    while(true)
    {
        int csock;
        if((csock = accept(server_sock, (sockaddr*)&client_sock, (socklen_t*)&addr_size)) != -1)
        {
            printf("Incomming connection from %s.\n", inet_ntoa(client_sock.sin_addr));
            memset(&cn_info,0, sizeof(connection_info));
            cn_info.sock_addr = client_sock;
            cn_info.sock = csock;
            std::thread thr(&server::new_connection, *this, cn_info);
            thr.join();
        }

    }
}

到目前为止。 server::new_connection() 仍然是空的。

最佳答案

问题出在这里:

std::thread thr(&server::new_connection, *this, cn_info);
                                         ^

您正在绑定(bind)服务器对象的拷贝;这是不可复制的,因为它包含(一个容器)不可复制的 thread 对象。相反,绑定(bind)一个指针:

std::thread thr(&server::new_connection, this, cn_info);

有些人可能会发现 lambda 更具可读性;这会按值捕获 this 指针和 cn_info:

std::thread thr([=]{new_connection(cn_info);});

正如评论者提到的,您可以通过绑定(bind) reference wrapper 来混淆解决方案:

std::thread thr(&server::new_connection, std::ref(*this), cn_info);

但我更愿意尽可能地消除而不是增加复杂性。

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

相关文章:

c++ - 析构函数如何删除嵌套的堆栈类型?

C++:出现奇怪的 header 错误

c++ - 获取窗口句柄

java - AspectJ - 使用aspectJ 获取生成lambda 函数的父线程的线程id

multithreading - 如何以线程安全的方式停止正在运行的任务?

java - 停止 ServerSocket Accept() 循环线程

java - 在java中将Object []转换为double []

c++ - 为什么我应该更喜欢使用成员初始化列表?

php - 转换包含单个键对象的数组

设置对象属性时出现 C++ 内存访问冲突