1. 程式人生 > >用C++11實現spinlock

用C++11實現spinlock

我的 spin lock 程式碼:

#include <atomic>
#include <unistd.h>
struct SpinLock;
struct SpinLock_t {
private:
  std::atomic<char> stat;
  static const char UNLOCK_STAT = 0;
  static const char LOCK_STAT = 1;
public:
  SpinLock_t() : stat(UNLOCK_STAT) {}
private:
  friend class SpinLock;
  SpinLock_t(const SpinLock_t& s); 
  SpinLock_t operator=(const SpinLock_t& s); 
};

struct SpinLock {
private:
  SpinLock_t *s_;
public:
  SpinLock(SpinLock_t* s):s_(s) {
    char unlock_stat = SpinLock_t::UNLOCK_STAT;
    while (!(s_->stat).compare_exchange_weak(unlock_stat,
      SpinLock_t::LOCK_STAT, std::memory_order_acq_rel)) {
      unlock_stat = SpinLock_t::UNLOCK_STAT;
      sleep(0);
    }   
  }
  ~SpinLock() {
    (s_->stat).store(SpinLock_t::UNLOCK_STAT, std::memory_order_release);
  }
private:
  SpinLock(const SpinLock& s); 
  SpinLock& operator=(const SpinLock& s); 
};

測試框架:

#include <vector>
#include <iostream>
#include <thread>
#include "SpinLock.h"
#include <mutex>
using namespace std;
SpinLock_t s;
std::mutex m;
int g = 0;
void f1() {
  for (int i = 0; i < 10000000; ++i) {
    m.lock();
    ++g;
    m.unlock();
  }
}
void f2() {
  for (int i = 0; i < 10000000; ++i) {
    {   
      SpinLock spinlock(&s);
      ++g;
    }   
  }
}
int main()
{
  std::vector<std::thread> v;
  for (int n = 0; n < 1; ++n) {
    v.emplace_back(f1);
    v.emplace_back(f2);
  }
  for (auto& t : v) {
    t.join();
  }
  cout << g << endl;
}

測試結果:

在併發嚴重的情況下,我實現的spinlock和mutex比,執行時間略長,總體效能略差。但是我實現的spinlock開銷的系統時間比mutex少了不少,spinlock本來就不是用於競爭非常嚴重、臨界區非常長的的場景:)