Я столкнулся с трудностями при использовании std::condition_variable
с моей собственной реализацией вращающегося мьютекса. Похоже, что std::condition_variable
ожидает, что std::mutex
будет связан с его блокировкой, что приводит к ошибкам компиляции при попытке использовать другую реализацию мьютекса.
Вот упрощенная версия моего кода, в которой возникает ошибка компиляции:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
class SpinMutex {
public:
void lock() {
// Implement spin lock logic here
}
void unlock() {
// Implement spin unlock logic here
}
private:
// Implement atomic flag or other spin lock mechanism here
};
SpinMutex mutex;
std::condition_variable cv;
bool ready = false;
void worker_thread() {
// Do some work...
std::this_thread::sleep_for(std::chrono::seconds(1));
// Attempting to lock a SpinMutex with std::lock_guard
// This line will throw a compilation error
std::unique_lock<SpinMutex> lock(mutex);
ready = true;
cv.notify_one();
}
int main() {
std::thread worker(worker_thread);
{
std::unique_lock<SpinMutex> lock(mutex);
cv.wait(lock, [] { return ready; });
}
worker.join();
return 0;
}
Как показано, использование std::unique_lock
с SpinMutex
вызывает ошибку компиляции. Похоже, что std::condition_variable
тесно связан с std::mutex, что делает его несовместимым с пользовательскими реализациями мьютекса, такими как спин-мьютекс.
Думаю, можно использовать std::condition_variable_any
, но у меня вопрос: почему стандарт решил пойти таким путем? Это из-за устаревших целей или потому, что они реализуют специальную оптимизацию для std::mutex
. Другими словами, для негениального разработчика, например. SpinMutex
выше, могу ли я гарантировать, что std::mutex
превзойдет мою собственную реализацию в целом?
Захват реализации VS
🤔 А знаете ли вы, что...
C++11, C++14, C++17 и C++20 - это различные версии стандарта C++, каждая из которых внесла свои улучшения.
Думаю, мне пригодится
std::condition_variable_any
Да исправить.
но мой вопрос: почему стандарт решил пойти таким путем?
Цель API синхронизации в C++ — предоставить переносимую оболочку API синхронизации ОС. А на дизайн API C++ большое влияние оказал API pthreads Linux.
Таким образом, std::mutex
и std::condition_variable
должны быть максимально тонкими оболочками базового API ОС. С точки зрения pthreads, std::mutex
сопоставляется с pthread_mutex_t
. И std::condition_variable
сопоставляется с pthread_cond_t
.
И pthread_cond_t
ждет pthread_mutex_t
. Но в то время стало понятно, что:
std::mutex
, иstd::mutex
.Таким образом, std::condition_variable_any
был разработан для удовлетворения потребностей тех, кто хочет дождаться обобщенной концепции мьютекса, не заставляя тех, кому эта общность не нужна, платить за эту функцию.
Вот ранняя статья с обоснованием дизайна:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html#condition
То, что в этой статье называется cond_var
, в конечном итоге было переименовано в condition_variable
. И то, что в этой статье называется gen_cond_var
, в конечном итоге было переименовано в condition_variable_any
.
Также следует отметить: в этой статье подробно рассказывается о сложности реализации gen_cond_var
. Однако в реализации этой статьи все еще существовала ошибка. Это было сложнее, чем тогда предполагали даже авторы. Однако, насколько мне известно, все основные реализации std::condition_variable_any
, начиная с C++11, не содержат ошибок.