C++ 在 for 循环中使用线程

Posted

技术标签:

【中文标题】C++ 在 for 循环中使用线程【英文标题】:C++ using threads in a for loop 【发布时间】:2021-12-13 21:45:06 【问题描述】:

这段代码有什么不同:

std::vector<Server> realsense_server_arr;
for (int i = 0; i < 1; ++i) 
    printf("Initializing server... %d\n", i);
    Server realsense_server(50000 + i);
    realsense_server.init_listener_thread();
    realsense_server_arr.emplace_back(realsense_server);

int depth_size = aligned_depth.get_width() * aligned_depth.get_height() * aligned_depth.get_bytes_per_pixel();
realsense_server_arr[0].update_buffer((unsigned char*)aligned_depth.get_data(), 10 * 4, depth_size);
int color_size = data.get_color_frame().get_width() * data.get_color_frame().get_height() * data.get_color_frame().get_bytes_per_pixel();
realsense_server_arr[0].update_buffer((unsigned char*)color.get_data(), 10*4 + depth_size, color_size);

// Send camera intrinsics and depth scale
realsense_server_arr[0].update_buffer((unsigned char*)color_intrinsics_arr, 0, 9 * 4);
realsense_server_arr[0].update_buffer((unsigned char*)&depth_scale, 9 * 4, 4);

对比这段代码:

Server realsense_server(50000);
realsense_server.init_listener_thread();

int depth_size = aligned_depth.get_width() * aligned_depth.get_height() * aligned_depth.get_bytes_per_pixel();
realsense_server.update_buffer((unsigned char*)aligned_depth.get_data(), 10 * 4, depth_size);

int color_size = data.get_color_frame().get_width() * data.get_color_frame().get_height() * data.get_color_frame().get_bytes_per_pixel();
realsense_server.update_buffer((unsigned char*)color.get_data(), 10 * 4 + depth_size, color_size);

// Send camera intrinsics and depth scale
realsense_server.update_buffer((unsigned char*)color_intrinsics_arr, 0, 9 * 4);
realsense_server.update_buffer((unsigned char*)&depth_scale, 9 * 4, 4);

它们在功能上是相同的(我认为?)。

第一个代码创建一个数组,添加一个 Server 对象,并根据 0 数组索引更新缓冲区。由于 i

第二个代码在没有数组的情况下执行相同的操作。

像这样访问数组中的线程对象有问题吗?

服务器代码在这里:https://github.com/andyzeng/visual-pushing-grasping/blob/580e2334beec0d83b49e6ca89d7542b79d1d4350/realsense/realsense.cpp#L24

第一个代码未能正确创建 TCP 服务器,它不响应消息并挂起。第二个代码成功。

【问题讨论】:

emplace_back中有复制操作。您可能希望在“放置”服务器时对其进行初始化,然后运行 ​​realsense_server_arr.back().init_listener_thread(); 你应该把服务器的代码放在这里,因为链接可能会过时,你的问题对其他用户来说毫无用处。 @AdrielJr 你抓住它真是太棒了。这正是问题所在。似乎我无法摆脱从 Python 专家到优秀 C++ 程序员的尝试……很多像这样的错综复杂的东西,如果不完全阅读 C++ 书籍可能无法学习 @AdrielJr 但是一个问题是,在我做出您建议的更改之后,如果我将“i 【参考方案1】:

前者复制realsense_server,将该副本放入向量中,然后仅对该副本执行操作。该副本的状态可以(并且从外观上看)与复制它的具体对象有很大不同。同样重要的是,具体对象 realsense_server 在离开 for 循环迭代时销毁

我什至不会开始建议我首先知道您正在使用的库,但我会建议您在这方面会取得更好的成功:

for (int i = 0; i < 1; ++i)

    printf("Initializing server... %d\n", i);
    realsense_server_arr.emplace_back(50000 + i);
    realsense_server_arr.last().init_listener_thread();

这将在向量尾部就地创建对象,并直接初始化那个对象的监听线程。如果i 的限制是已知的并且大于1(我希望是这样,否则这几乎没有意义),您可能希望首先保留向量容量。即,

std::vector<Server> realsense_server_arr;
realsense_server_arr.reserve(n);

for (int i = 0; i < n; ++i)

    printf("Initializing server... %d\n", i);
    realsense_server_arr.emplace_back(50000 + i);
    realsense_server_arr.last().init_listener_thread();

【讨论】:

一个问题是,在我做出你建议的改变之后,如果我将“i 我不能告诉你。正如我所说,我不是 RealSense 人,只是一个 C++ 人。但是,调试器可能会很快将您指出问题所在。但是,此答案中的上述代码应该是合理的。 我觉得跟服务器代码或者TCP代码有关

以上是关于C++ 在 for 循环中使用线程的主要内容,如果未能解决你的问题,请参考以下文章

C++ uWebSockets 在一个线程中集成事件循环

在 C++ 中实现“临时可暂停”并发循环

运行方法并等待完成所有 for 循环 openmp

加速总结循环的多线程 C++ 程序

什么是并行 for 循环,应该如何/何时使用它?

C++ OpenMP 并行 For 循环 - std::vector 的替代品 [关闭]