File tree Expand file tree Collapse file tree 8 files changed +98
-89
lines changed
Expand file tree Collapse file tree 8 files changed +98
-89
lines changed Original file line number Diff line number Diff line change @@ -66,9 +66,9 @@ add_subdirectory(LinkedList)
6666add_subdirectory (Memcpy)
6767add_subdirectory (MonitorDir)
6868add_subdirectory (MonitorDir_EFSW)
69- add_subdirectory (Mutex)
7069add_subdirectory (OpenSSL)
7170add_subdirectory (SafeCallback)
71+ add_subdirectory (SpinMutex)
7272add_subdirectory (Thread)
7373
7474if (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 3535 1 . 获取事件发生文件所在的上级路径中,使用了` open_by_handle_at ` 这个方法,普通用户下会出现` Operation not permitted ` 错误,也需要` CAP_SYS_ADMIN ` 能力,即root权限;
3636 2 . 建议使用root权限运行,如果一定要在普通用户下运行,还是建议使用` inotify ` 而不是` fanotify ` ,反正在打开一个监控文件描述符(` fd ` )的情况下,都无法实现` subtree ` 监控;
373723 . [ 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的一些例子;
4039 1 . [ aes] ( /OpenSSL/openssl_aes.cc ) ——aes加解密的例子;
4140 2 . [ base64] ( /OpenSSL/openssl_base64.cc ) ——base64编解码的例子;
4241 3 . [ hash] ( /OpenSSL/openssl_hash.cc ) ——sha256的例子;
4645 7 . [ sm4] ( /OpenSSL/openssl_sm4.cc ) ——sm4加解密的例子;
4746 8 . [ x509] ( /OpenSSL/openssl_x509.cc ) ——x509证书的例子;
4847 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的一些例子;
5150 1 . [ server_epoll] ( /Server/server_epoll.cc ) ——epoll的例子;
5251 2 . [ server_poll] ( /Server/server_poll.cc ) ——poll的例子;
5352 3 . [ server_select] ( /Server/server_select.cc ) ——select的例子;
53+ 27 . [ SpinMutex] ( /SpinMutex ) ——使用std::atomic_flag实现的简单互斥锁和自旋锁;
545428 . [ Thread] ( /Thread/ ) ——基于std::thread实现的线程类,包括线程池;
5555 1 . [ Thread] ( /Thread/thread.hpp ) ——线程类;
5656 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+ for (int j = 0 ; j < 1000 ; ++j) {
14+ SpinMutexLocker locker (&mutex);
15+ ++counter;
16+ }
17+ });
18+ }
19+
20+ for (auto &thread : threads) {
21+ thread.join ();
22+ }
23+
24+ EXPECT_EQ (counter, 10000 );
25+ }
26+
27+ int main (int argc, char **argv)
28+ {
29+ ::testing::InitGoogleTest (&argc, argv);
30+ return RUN_ALL_TESTS ();
31+ }
You can’t perform that action at this time.
0 commit comments