C++中有一种类似于Java,甚至更强大的synchronized

在C++11及以后的版本中有std::mutex和std::lock_guard,它们是简单的类,因此即使在旧的C++版本中,也可以在几秒钟内自己实现。但是,对于具有明确排他作用域的Java/C#的synchronized语法,我常常会嫉妒地写这样的宏。(对吧?)

#define synchronized(monitor) \
  if (auto __lock = std::make_unique<std::lock_guard<std::mutex>>(monitor))

這樣的定義好了

std::vector<int> data_;  // いろんなスレッドから読み書きするデータ
std::mutex monitor_;     // mutexオブジェクトを宣言しておいて

...

synchronized (motinor_) {
  // 排他制御された処理
  data_.doSomething();
}

Java哦,哎呀。

现在我们来超越Java。
程序员的意图是希望确保“data_只能由自己的线程来处理”,monitor_这个存在比意图更低级、更嘈杂。在Java中,可以使用synchronized(data_)将data_本身作为监视器的角色(即synchronized(data_)的写法),但这种技巧并不好,所以通常会单独准备一个monitor_来使用。
而在C++中,你甚至可以将这一点隐藏在宏中,使得程序员看不到。

// 先ほどのsynchronizedの定義に追加します。

// モニタ変数の名前は _mutex_【対象変数名】 だ
#define MONITOR_OF(var) _mutex_ ## var

// 変数宣言とそれ専用のモニタ変数宣言をやってくれる
#define DECLARE_THREAD_SAFE(type, var) \
  type var; \
  std::mutex MONITOR_OF(var);

// 独占使用したい変数を指定する記法
#define exclusive(var) synchronized(MONITOR_OF(var))

这样做,data_的专属使用就会变成这样。

DECLARE_THREAD_SAFE(std::vector<int>, data_)  // いろんなスレッドから読み書きするデータ

...

exclusive (data_) {
  // 排他制御された処理
  data_.doSomething();
}

这个同步宏虽然使用了make_unique来放在if语法的框架上,但我觉得这种方式有些复杂和不美观。有没有什么更好的写法呢?比如使用for而非if?

广告
将在 10 秒后关闭
bannerAds