如何让提升池访问 gsl 矩阵以线程化任务
How to give boost pool access to a gsl matrix for threading a task
我有一个 gsl 矩阵,我一遍又一遍地填充它,在一个线程上完成所有操作非常繁重。是否可以在增强池线程中修改 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)
感谢您的宝贵时间。
所有线程始终“有权访问”整个 进程 space - 即该进程内存中的所有对象。
原则上,不需要在进程内“授予 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
(还修复了内存泄漏问题)。
旁注:
您可能希望使用 futures 来同步任务。另请注意,通过引用捕获指针是不必要的。
我有一个 gsl 矩阵,我一遍又一遍地填充它,在一个线程上完成所有操作非常繁重。是否可以在增强池线程中修改 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)
感谢您的宝贵时间。
所有线程始终“有权访问”整个 进程 space - 即该进程内存中的所有对象。
原则上,不需要在进程内“授予 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
(还修复了内存泄漏问题)。
旁注:
您可能希望使用 futures 来同步任务。另请注意,通过引用捕获指针是不必要的。