std::atomic_flag实现自旋锁和互斥锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Mutex
{
DISABLE_COPY(Mutex)
public:
Mutex() {}
~Mutex() {}

void lock()
{
while (m_atomic_flag.test_and_set(std::memory_order_acquire)) {
// 有这一行 ? 互斥锁:自旋锁;
// std::this_thread::yield();
}
}

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

private:
std::atomic_flag m_atomic_flag;
};

RAII锁定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MutexLocker
{
Mutex *m_mutex;

DISABLE_COPY(MutexLocker)
public:
MutexLocker(Mutex *mutex)
: m_mutex(mutex)
{
m_mutex->lock();
}

~MutexLocker() { m_mutex->unlock(); }
};

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class TestMutex
{
Mutex m_mutex;
int count = 0;

public:
void run()
{
while (count < 30) {
MutexLocker locker(&m_mutex);
std::cout << std::this_thread::get_id() << ": " << ++count << std::endl;
}
}
};

int main(int argc, char *argv[])
{
TestMutex test;
std::thread t1(std::bind(&TestMutex::run, &test));
std::thread t2(std::bind(&TestMutex::run, &test));
t1.join();
t2.join();

return 0;
}

结果

自旋

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
19616: 1
17472: 2
19616: 3
19616: 4
19616: 5
19616: 6
17472: 7
17472: 8
19616: 9
17472: 10
17472: 11
17472: 12
17472: 13
17472: 14
17472: 15
17472: 16
17472: 17
17472: 18
19616: 19
17472: 20
19616: 21
17472: 22
19616: 23
17472: 24
19616: 25
17472: 26
19616: 27
17472: 28
19616: 29
17472: 30
19616: 31

互斥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
16476: 1
16476: 2
16476: 3
16476: 4
16476: 5
16476: 6
16476: 7
16476: 8
16476: 9
16476: 10
16476: 11
16476: 12
16476: 13
16476: 14
16476: 15
16476: 16
16476: 17
16476: 18
16476: 19
16476: 20
16476: 21
16476: 22
17104: 23
16476: 24
16476: 25
16476: 26
16476: 27
16476: 28
16476: 29
16476: 30
17104: 31