有没有办法在没有 lambda 的情况下使用 std::condition_variable::wait(lock, pred) ?

Sie*_*ose 2 c++ lambda multithreading condition-variable

我在网上找到了这段代码,解释了如何使用 astd::condition_variable来解决生产者-消费者问题:Producer-Consumer Problem using Condition Variable in C++

#include <condition_variable> // std::condition_variale
#include <cstdlib>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;

std::mutex g_mutex;
std::condition_variable g_cv;

bool g_ready = false;
int g_data = 0;

int produceData() {
  int randomNumber = rand() % 1000;
  std::cout << "produce data: " << randomNumber << "\n";
  return randomNumber;
}

void consumeData(int data) { std::cout << "receive data: " << data << "\n"; }

void consumer() {
  int data = 0;
  while (true) {
    std::unique_lock<std::mutex> ul(g_mutex);
    g_cv.wait(ul, []() { return g_ready; });
    consumeData(g_data);
    g_ready = false;
    ul.unlock();
    g_cv.notify_one();
  }
}

void producer() {
  while (true) {
    std::unique_lock<std::mutex> ul(g_mutex);
    g_data = produceData();
    g_ready = true;
    ul.unlock();
    g_cv.notify_one();
    ul.lock();
    g_cv.wait(ul, []() { return g_ready == false; });
  }
}

void consumerThread(int n) { consumer(); }

void producerThread(int n) { producer(); }

int main() {
  int times = 100;
  std::thread t1(consumerThread, times);
  std::thread t2(producerThread, times);
  t1.join();
  t2.join();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的代码可以工作,但我的编码标准规定我不允许使用 lambda。如何在不使用 lambda 的情况下使用此代码wait()

我尝试了以下方法,但没有成功:

  1. 使用正常的bool
wait(g_ready)
Run Code Online (Sandbox Code Playgroud)

Jan*_*tke 8

正如评论者指出的那样,对于编码标准来说,禁止 lambda 是一个可疑的决定。无论如何,lambda 只是使用调用运算符创建类型的便捷语法,您可以手动完成此操作。

具有可调用结构的解决方案

拉姆达表达式:

[]() { return g_ready; }
Run Code Online (Sandbox Code Playgroud)

大致翻译为

struct g_ready_checker {
    bool operator()() const noexcept {
        return g_ready;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后您可以执行以下操作:

g_cv.wait(ul, g_ready_checker{});
Run Code Online (Sandbox Code Playgroud)

我们还可以变成g_ready_checker带有参数的类模板,或者我们可以存储作为类成员的<bool DesiredValue>值。g_ready

具有免费功能的解决方案

或者,由于这个 lambda 不捕获任何内容,您也可以编写一个自由函数,可能作为模板:

template <bool DesiredValue>
bool is_g_ready() {
    return g_ready == DesiredValue;
}

/* ... */
g_cv.wait(ul, &is_g_ready<true>);
/* ... */
g_cv.wait(ul, &is_g_ready<false>);
Run Code Online (Sandbox Code Playgroud)

在这里,我们提供了wait一个谓词,它是一个函数指针。请注意, 的Predicate模板参数std::condition_variable_wait不限于 lambda,它接受任何可返回可转换内容的可调用内容bool