Spinlock

111 阅读1分钟

以下是一个示例,演示了如何在 C++ 中使用自旋锁(Spinlock)实现线程之间的同步:

#include <iostream>
#include <thread>
#include <atomic>

class Spinlock {
public:
    Spinlock() : flag(ATOMIC_FLAG_INIT) {}

    void lock() {
        while (flag.test_and_set(std::memory_order_acquire)) {}
    }

    void unlock() {
        flag.clear(std::memory_order_release);
    }

private:
    std::atomic_flag flag;
};

// 共享资源
int sharedData = 0;
Spinlock spinlock;

// 线程函数,对共享资源进行操作
void threadFunction(int id) {
    for (int i = 0; i < 5; ++i) {
        // 使用自旋锁保护共享资源
        spinlock.lock();
        std::cout << "Thread " << id << " accessing shared data: " << sharedData << std::endl;
        ++sharedData;
        std::cout << "Thread " << id << " updated shared data: " << sharedData << std::endl;
        spinlock.unlock();
        
        // 模拟一些工作
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

int main() {
    // 创建两个线程
    std::thread t1(threadFunction, 1);
    std::thread t2(threadFunction, 2);

    // 等待线程执行完成
    t1.join();
    t2.join();

    return 0;
}

在这个示例中,我们定义了一个自旋锁 Spinlock,它使用了 C++11 中的 std::atomic_flag 来实现。自旋锁的 lock() 方法会一直忙等(自旋)直到获取到锁为止,而不会让线程进入阻塞状态。

在线程函数 threadFunction 中,我们使用自旋锁来保护对共享资源 sharedData 的访问。在每次操作共享资源前,我们调用 lock() 方法来获取自旋锁,然后对共享资源进行操作,最后调用 unlock() 方法来释放自旋锁。

这样做可以确保同时只有一个线程可以访问共享资源,从而避免了竞态条件(Race Condition)的发生,保证了线程安全性。