Commit 6d3dcd7 1 parent 42847d8 commit 6d3dcd7 Copy full SHA for 6d3dcd7
File tree 8 files changed +123
-89
lines changed
8 files changed +123
-89
lines changed Original file line number Diff line number Diff line change @@ -66,9 +66,9 @@ add_subdirectory(LinkedList)
66
66
add_subdirectory (Memcpy)
67
67
add_subdirectory (MonitorDir)
68
68
add_subdirectory (MonitorDir_EFSW)
69
- add_subdirectory (Mutex)
70
69
add_subdirectory (OpenSSL)
71
70
add_subdirectory (SafeCallback)
71
+ add_subdirectory (SpinMutex)
72
72
add_subdirectory (Thread)
73
73
74
74
if (CMAKE_HOST_LINUX)
Load Diff This file was deleted.
Load Diff This file was deleted.
Load Diff This file was deleted.
Original file line number Diff line number Diff line change 35
35
1 . 获取事件发生文件所在的上级路径中,使用了` open_by_handle_at ` 这个方法,普通用户下会出现` Operation not permitted ` 错误,也需要` CAP_SYS_ADMIN ` 能力,即root权限;
36
36
2 . 建议使用root权限运行,如果一定要在普通用户下运行,还是建议使用` inotify ` 而不是` fanotify ` ,反正在打开一个监控文件描述符(` fd ` )的情况下,都无法实现` subtree ` 监控;
37
37
23 . [ MonitorDir_EFSW] ( /MonitorDir_EFSW/main.cc ) ——使用efsw实现的目录监控的简单例子;
38
- 24 . [ Mutex] ( /Mutex/mutex.hpp ) ——使用std::atomic_flag实现的简单互斥锁和自旋锁;
39
- 25 . [ OpenSSL] ( /OpenSSL ) ——openssl的一些例子;
38
+ 24 . [ OpenSSL] ( /OpenSSL ) ——openssl的一些例子;
40
39
1 . [ aes] ( /OpenSSL/openssl_aes.cc ) ——aes加解密的例子;
41
40
2 . [ base64] ( /OpenSSL/openssl_base64.cc ) ——base64编解码的例子;
42
41
3 . [ hash] ( /OpenSSL/openssl_hash.cc ) ——sha256的例子;
46
45
7 . [ sm4] ( /OpenSSL/openssl_sm4.cc ) ——sm4加解密的例子;
47
46
8 . [ x509] ( /OpenSSL/openssl_x509.cc ) ——x509证书的例子;
48
47
9 . [ bash] ( /OpenSSL/openssl_bash.sh ) ——openssl命令行的例子;
49
- 26 . [ SafeCallback] ( /SafeCallback/safecallback.hpp ) ——生命周期安全的回调函数的实现,参考[ muduo WeakCallback] ( https://github.com/chenshuo/muduo/blob/cpp17/muduo/base/WeakCallback.h ) ;
50
- 27 . [ Server] ( /Server ) ——linux server的一些例子;
48
+ 25 . [ SafeCallback] ( /SafeCallback/safecallback.hpp ) ——生命周期安全的回调函数的实现,参考[ muduo WeakCallback] ( https://github.com/chenshuo/muduo/blob/cpp17/muduo/base/WeakCallback.h ) ;
49
+ 26 . [ Server] ( /Server ) ——linux server的一些例子;
51
50
1 . [ server_epoll] ( /Server/server_epoll.cc ) ——epoll的例子;
52
51
2 . [ server_poll] ( /Server/server_poll.cc ) ——poll的例子;
53
52
3 . [ server_select] ( /Server/server_select.cc ) ——select的例子;
53
+ 27 . [ SpinMutex] ( /SpinMutex ) ——使用std::atomic_flag实现的简单互斥锁和自旋锁;
54
54
28 . [ Thread] ( /Thread/ ) ——基于std::thread实现的线程类,包括线程池;
55
55
1 . [ Thread] ( /Thread/thread.hpp ) ——线程类;
56
56
2 . [ ThreadPool] ( /Thread/threadpool.hpp ) ——线程池;
Original file line number Diff line number Diff line change
1
+ add_executable (spinmutex_unittest spinmutex_unittest.cc spinmutex.hpp)
2
+ target_link_libraries (spinmutex_unittest PRIVATE GTest::gtest GTest::gtest_main
3
+ GTest::gmock GTest::gmock_main)
4
+ add_test (NAME spinmutex_unittest COMMAND spinmutex_unittest)
5
+
6
+ if (CMAKE_HOST_UNIX )
7
+ target_link_libraries (spinmutex_unittest PRIVATE pthread)
8
+ endif ()
Original file line number Diff line number Diff line change
1
+ #pragma once
2
+
3
+ #include < utils/object.hpp>
4
+
5
+ #include < atomic>
6
+ #include < cassert>
7
+ #include < iostream>
8
+ #include < thread>
9
+
10
+ class SpinMutex : noncopyable
11
+ {
12
+ public:
13
+ SpinMutex () { m_atomic_flag.clear (std::memory_order_release); }
14
+
15
+ ~SpinMutex ()
16
+ {
17
+ if (m_atomic_flag.test_and_set (std::memory_order_acquire)) {
18
+ assert (false && " SpinLock destroyed while locked!" );
19
+ std::cerr << " Error: SpinLock destroyed while locked!" << std::endl;
20
+ }
21
+ m_atomic_flag.clear (std::memory_order_release);
22
+ }
23
+
24
+ void lock ()
25
+ {
26
+ while (m_atomic_flag.test_and_set (std::memory_order_acquire)) {
27
+ std::this_thread::yield (); // 有这一行,就是自旋锁;没有这一行,就是互斥锁(忙等待)
28
+ }
29
+ }
30
+
31
+ void unlock () { m_atomic_flag.clear (std::memory_order_release); }
32
+
33
+ private:
34
+ std::atomic_flag m_atomic_flag;
35
+ };
36
+
37
+ class SpinMutexLocker : noncopyable
38
+ {
39
+ SpinMutex *m_mutex = nullptr ;
40
+
41
+ public:
42
+ SpinMutexLocker (SpinMutex *mutex)
43
+ : m_mutex(mutex)
44
+ {
45
+ assert (m_mutex);
46
+ m_mutex->lock ();
47
+ }
48
+
49
+ ~SpinMutexLocker ()
50
+ {
51
+ assert (m_mutex);
52
+ m_mutex->unlock ();
53
+ }
54
+ };
Original file line number Diff line number Diff line change
1
+ #include " spinmutex.hpp"
2
+
3
+ #include < gtest/gtest.h>
4
+
5
+ TEST (SpinMutexTest, MultiThreadIncrement)
6
+ {
7
+ SpinMutex mutex;
8
+ std::vector<std::thread> threads;
9
+ int counter = 0 ;
10
+
11
+ for (int i = 0 ; i < 10 ; ++i) {
12
+ threads.emplace_back ([&] {
13
+ SpinMutexLocker locker (&mutex);
14
+ for (int j = 0 ; j < 1000 ; ++j) {
15
+ ++counter;
16
+ }
17
+ });
18
+ }
19
+
20
+ for (auto &thread : threads) {
21
+ thread.join ();
22
+ }
23
+
24
+ EXPECT_EQ (counter, 10000 );
25
+ }
26
+
27
+ TEST (SpinMutexTest, DestructionWhileLocked)
28
+ {
29
+ SpinMutex *mutex = new SpinMutex;
30
+ mutex->lock ();
31
+ ASSERT_THROW ({ delete mutex; }, std::logic_error);
32
+ }
33
+
34
+ TEST (SpinMutexTest, ExceptionSafety)
35
+ {
36
+ SpinMutex mutex;
37
+ bool threw = false ;
38
+
39
+ try {
40
+ mutex.lock ();
41
+ throw std::runtime_error (" Simulated exception" );
42
+ mutex.unlock ();
43
+ } catch (...) {
44
+ threw = true ;
45
+ }
46
+
47
+ mutex.lock ();
48
+ mutex.unlock ();
49
+ EXPECT_TRUE (threw);
50
+ }
51
+
52
+ int main (int argc, char **argv)
53
+ {
54
+ ::testing::InitGoogleTest (&argc, argv);
55
+ return RUN_ALL_TESTS ();
56
+ }
You can’t perform that action at this time.
0 commit comments