如何让提升池访问 gsl 矩阵以线程化任务
Posted
技术标签:
【中文标题】如何让提升池访问 gsl 矩阵以线程化任务【英文标题】:How to give boost pool access to a gsl matrix for threading a task 【发布时间】:2020-07-16 23:42:43 【问题描述】:我有一个 gsl 矩阵,我一遍又一遍地填充它,并且在一个线程上完成所有操作非常繁重。是否可以在 boost pool 线程中修改 gsl 矩阵?
#include <gsl/gsl_linalg.h>
#include <boost/asio.hpp>
int main()
int SIZE = 3; // small size
gsl_matrix * _A = gsl_matrix_alloc(SIZE, SIZE); // set the gsl matrix to 3x3
gsl_matrix_set_all(_A, 0); // make them all 0 to provide contrast if value changes
auto _dostuff = [&_A]()
gsl_matrix_set (_A, 0, 0, 20); // set the (0, 0) position to 20
;
boost::asio::thread_pool pool(1); // open up a thread pool containing 1 thread
boost::asio::post(pool, [&_A, &_dostuff]_dostuff() ;); // post a task to the pool
std::cout << gsl_matrix_get (_A, 0, 0) << std::endl; // check to see if the (0, 0) position is 20 (its not)
return 0;
您需要将以下行添加到您的 Cmake 中
SET(CMAKE_CXX_FLAGS $CMAKE_CXX_FLAGS "-std=c++17 -pthread")
find_package(GSL REQUIRED)
target_link_libraries(<folder name> GSL::gsl GSL::gslcblas)
感谢您的宝贵时间。
【问题讨论】:
【参考方案1】:所有线程始终“有权访问”整个进程空间 - 即该进程的内存中的所有对象。
原则上,不需要在进程内“授予 X 访问权限”。
这里:
post(pool, [&_A, &_dostuff] _dostuff(); ); // post a task to the pool
您过于冗长,这可能表明您的困惑。 _dostuff
已经捕获了矩阵,所以你不需要它。此外,如果您需要捕获 lambda,您可以按值执行(这通常是更安全的默认设置,尤其是在线程化时):
post(pool, [=] _dostuff(); );
具有讽刺意味的是,您可以简单地将其替换为
post(pool, _dostuff);
为什么它不起作用?
很好用。您的支票中只是有数据竞争 - 所以任何事情都可能发生 (https://en.wikipedia.org/wiki/Undefined_behavior)。
为了获得可靠的检查,您可以先加入线程池:
#include <boost/asio.hpp>
#include <gsl/gsl_linalg.h>
#include <iostream>
namespace ba = boost::asio;
int main()
int SIZE = 3; // small size
gsl_matrix* _A = gsl_matrix_alloc(SIZE, SIZE); // 3x3
gsl_matrix_set_all(_A, 0); // zero for reference
auto _dostuff = [_A]()
gsl_matrix_set(_A, 0, 0, 20); // set (0, 0) to 20
;
ba::thread_pool pool(1); // one thread
post(pool, _dostuff); // post task
pool.join();
std::cout
<< gsl_matrix_get(_A, 0, 0)
<< std::endl;
gsl_matrix_free(_A);
打印
20
(也修复了内存泄漏)。
旁注:
您可能希望使用期货来同步任务。另请注意,通过引用捕获指针是不必要的。
【讨论】:
按值传递指针是否会复制任何内容?我通过引用传递速度,但是如果按值传递的指针只是让指针访问矩阵,那么是的,我可以按值传递。你能解释一下吗?谢谢 这是否比通过引用传递指针的计算成本更高?还是您只是在说明它可以被复制和按值传递? 指针复制起来很便宜。引用是......只是引擎盖下的指针(但它们不能为空)以上是关于如何让提升池访问 gsl 矩阵以线程化任务的主要内容,如果未能解决你的问题,请参考以下文章
Java面试小短文当任务数超过线程池的核心线程数,如何让它不进入阻塞队列直接启用最大数量的线程去执行任务?