gpt4 book ai didi

c++ - 将 CSocket 传递给 std::thread

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:46:21 26 4
gpt4 key购买 nike

我正在使用 CSocket 编写多线程服务器。所以,像往常一样,我有监听服务器套接字,并且需要为每个连接的客户端创建接收套接字。为了提供多个客户端处理,我想为每个客户端创建新的 std::thread分离 它,然后在线程函数中处理这个客户端。


我正在尝试这样做:

int client_handler(CSocket receiver)
{
return 1;
}

CSocket server;
BOOL created = server.Create(12345);
server.Listen();
while(true)
{
CSocket receiver;
if (server.Accept(receiver))
{
std::thread handler(client_handler, receiver);
}

}
...

我在 std::thread 实例化时遇到编译器错误:

error C2664: 'std::tuple<int (__cdecl *)(CSocket),CSocket>::tuple(std::tuple<int (__cdecl *)(CSocket),CSocket> &&)': cannot convert argument 1 from 'int (__cdecl &)(CSocket)' to 'std::allocator_arg_t'

我已经阅读了 std::thread 文档,但仍然无法理解 - 为什么不能将 СSocket 传递给?

最佳答案

问题:

您使用 CSocket线程实例化中的对象,按值传递它。传递给 std::thread 的可调用参数应可移动或复制构造。不幸的是,CSocket 既不可复制也不可移动,这就是您收到错误的原因。

解决方案:

另一种方法是通过引用传递套接字。在这种情况下,您必须用 std::ref() 包装它,以避免您的线程收到对拷贝的引用。但是你不能在这里考虑这个替代方案,因为 receiver 是一个具有本地存储的对象。它可能会在线程完成之前被销毁,从而导致未定义的行为。

那么有两种可能性:

  1. receiver 作为您类(class)的成员,或者至少确保它在线程完成之前可用。引用方法将变得可行
  2. 动态创建 CSocket,使用 shared_ptr 并在线程实例化(和 client_handler() 中)传递此 shared_ptr

评论:

虽然与您当前的问题并不严格相关,但请注意,在您的代码片段中,您将 handler 创建为 if-bloc 的本地对象。因此,当您离开集团并且没有加入线程时,该对象将被销毁。这会导致UB:你必须在销毁相应的线程对象之前加入或分离线程。

因此,要么更改代码结构以考虑此约束并自行管理线程,要么考虑使用 std::async()如果您只想异步执行接收代码。

关于c++ - 将 CSocket 传递给 std::thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37612881/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com