如何让提升池访问 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 来同步任务。另请注意,通过引用捕获指针是不必要的。