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");
}