Lösungsvorschlag
Die gewünschte RAII-Klasse kann recht einfach formuliert werden:
struct Guard {
Guard(std::mutex& mutex) : mutex(mutex) {
mutex.lock();
}
~Guard() {
mutex.unlock();
}
std::mutex& mutex;
};
Dann vereinfacht sich die gen()-Methode:
double gen() { Guard guard(mutex); return uniform(mt); }
Es dürfte nicht sehr überraschen, dass es eine entsprechende Klasse in der Standardbibliothek für C++ bereits gibt. Sie nennt sich std::lock_guard und erhält die Mutex-Klasse als Template-Parameter:
double gen() { std::lock_guard<std::mutex> guard(mutex); return uniform(mt); }
#include <thread> #include <random> #include <mutex> #include <vector> #include <cstdlib> #include <hpc/matvec/gematrix.h> #include <hpc/matvec/apply.h> #include <hpc/matvec/print.h> #include <hpc/aux/slices.h> struct Guard { Guard(std::mutex& mutex) : mutex(mutex) { mutex.lock(); } ~Guard() { mutex.unlock(); } std::mutex& mutex; }; struct MyRandomGenerator { MyRandomGenerator() : mt(std::random_device()()), uniform(-100, 100) { } double gen() { Guard guard(mutex); return uniform(mt); } private: std::mutex mutex; std::mt19937 mt; std::uniform_real_distribution<double> uniform; }; template<typename MA, typename RNG> typename std::enable_if<hpc::matvec::IsRealGeMatrix<MA>::value, void>::type randomInit(MA& A, RNG& rng) { using ElementType = typename MA::ElementType; using Index = typename MA::Index; hpc::matvec::apply(A, [&](ElementType& val, Index i, Index j) -> void { val = rng.gen(); }); } int main() { using namespace hpc::matvec; using namespace hpc::aux; MyRandomGenerator rng; GeMatrix<double> A(51, 7); unsigned int nof_threads = std::thread::hardware_concurrency(); std::vector<std::thread> threads(nof_threads); Slices<GeMatrix<double>::Index> slices(nof_threads, A.numRows); for (int index = 0; index < nof_threads; ++index) { auto firstRow = slices.offset(index); auto numRows = slices.size(index); auto A_ = A(firstRow, 0, numRows, A.numCols); threads[index] = std::thread([=,&rng]() mutable { randomInit(A_, rng); }); } for (int index = 0; index < nof_threads; ++index) { threads[index].join(); } print(A, "A"); }