спин-блокировки в C++ и Ubuntu 24?
Я использую реализацию спин-блокировки в https://rigtorp.se/spinlock/
Это определяет спин-блокировку в структуре и работает правильно.
Но если та же реализация спин-блокировки инкапсулирована в класс C++,
операция блокировки зависает.
/>Знаете, почему это происходит?
Подробнее см. ниже спин-блокировку, инкапсулированную в класс Spinlock_class,
и ту же спин-блокировку в структуре Spinlock_struct.
Подробные сведения о том, как скомпилировать и запустить этот пример, приведены в конце.
Следующий код показывает проблему.
Код: Выделить всё
#include
#include
class Spinlock_class
{
public:
void Lock() noexcept
{
for (;;)
{
// Optimistically assume the lock is free on the first try.
if (lock_.exchange(true, std::memory_order_acquire)) {
return;
}
// Wait for the lock to be released without generating cache misses.
while (lock_.load(std::memory_order_relaxed)) {
// Issue X86 PAUSE or ARM YIELD instruction to reduce contention between hyper threads.
__builtin_ia32_pause();
}
}
}
bool TryLock() noexcept
{
// First do a relaxed load to check if the lock is free in order to prevent
// unnecessary cache misses if someone does while(!try_lock()).
return !lock_.load(std::memory_order_relaxed) &&
!lock_.exchange(true, std::memory_order_acquire);
}
void Unlock() noexcept
{
lock_.store(false, std::memory_order_release);
}
private:
std::atomic lock_ = {false};
};
struct Spinlock_struct {
std::atomic lock_ = {0};
void lock() noexcept {
for (;;) {
// Optimistically assume the lock is free on the first try
if (!lock_.exchange(true, std::memory_order_acquire)) {
return;
}
// Wait for lock to be released without generating cache misses
while (lock_.load(std::memory_order_relaxed)) {
// Issue X86 PAUSE or ARM YIELD instruction to reduce contention between
// hyper-threads
__builtin_ia32_pause();
}
}
}
bool try_lock() noexcept {
// First do a relaxed load to check if lock is free in order to prevent
// unnecessary cache misses if someone does while(!try_lock())
return !lock_.load(std::memory_order_relaxed) &&
!lock_.exchange(true, std::memory_order_acquire);
}
void unlock() noexcept {
lock_.store(false, std::memory_order_release);
}
};
int main(int argc, char* argv[])
{
Spinlock_class sl_c;
Spinlock_struct sl_s;
std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/79806993/a-spinlock-in-a-struct-works-properly-but-the-same-spinlock-in-a-c-class-hangs[/url]
Мобильная версия