7
7
#include < chrono>
8
8
#include < condition_variable>
9
9
#include < functional>
10
+ #include < iostream>
10
11
#include < mutex>
11
12
#include < thread>
12
13
13
14
class Thread : noncopyable
14
15
{
15
16
public:
16
- using Task = std::function<void ()>;
17
+ using Task = std::function<void (std::stop_token )>;
17
18
18
19
Thread () = default ;
19
- explicit Thread (Task task) { setTask (std::move (task)); }
20
+
21
+ explicit Thread (Task task)
22
+ : m_task(std::move(task))
23
+ {}
24
+
20
25
~Thread () { stop (); }
21
26
22
- void setTask (Task task) { m_task = std::move (task); }
27
+ void setTask (Task task)
28
+ {
29
+ std::lock_guard<std::mutex> lock (m_mutex);
30
+ m_task = std::move (task);
31
+ }
23
32
24
- void start ()
33
+ bool start ()
25
34
{
26
- m_running.store (true );
27
- m_thread = std::thread ([this ]() {
28
- m_condition.notify_one ();
35
+ if (m_jthread.joinable ()) {
36
+ return false ;
37
+ }
38
+
39
+ m_jthread = std::jthread ([this ](std::stop_token token) {
40
+ m_running.store (true );
41
+ m_running.notify_all ();
29
42
if (m_task) {
30
- m_task ();
43
+ try {
44
+ m_task (token);
45
+ } catch (const std::exception &e) {
46
+ std::cerr << " Thread exception: " << e.what () << std::endl;
47
+ }
31
48
}
49
+
50
+ m_running.store (false );
51
+ m_running.notify_all ();
32
52
});
53
+
54
+ return true ;
33
55
}
34
56
35
57
void stop ()
36
58
{
37
- if (m_thread.joinable ()) {
38
- m_thread.join ();
59
+ if (m_jthread.joinable ()) {
60
+ m_jthread.request_stop ();
61
+ m_jthread.join ();
39
62
}
63
+
40
64
m_running.store (false );
41
65
}
42
66
67
+ void interrupt ()
68
+ {
69
+ if (m_jthread.joinable ()) {
70
+ m_jthread.request_stop ();
71
+ std::cout << " Thread interrupted: " << m_jthread.get_id () << std::endl;
72
+ }
73
+ }
74
+
43
75
void waitForStarted ()
44
76
{
45
- std::unique_lock<std::mutex> lock (m_mutex);
46
- m_condition.wait (lock, [this ]() { return m_running.load (); });
77
+ while (!m_running.load ()) {
78
+ m_running.wait (false );
79
+ }
80
+ }
81
+ void waitForFinished ()
82
+ {
83
+ while (m_running.load ()) {
84
+ m_running.wait (true );
85
+ }
47
86
}
48
87
49
- [[nodiscard]] auto isRunning () const -> bool { return m_running; }
88
+ [[nodiscard]] bool isRunning () const { return m_running. load () ; }
50
89
51
- [[nodiscard]] auto getThreadId () const -> std::thread::id { return m_thread .get_id (); }
90
+ [[nodiscard]] std::thread::id getThreadId () const { return m_jthread .get_id (); }
52
91
53
92
static void yield () { std::this_thread::yield (); }
54
93
@@ -64,15 +103,14 @@ class Thread : noncopyable
64
103
65
104
static auto hardwareConcurrency () -> unsigned int
66
105
{
67
- auto availableCores = std::thread::hardware_concurrency (); // 如果不支持,返回0
106
+ auto availableCores = std::thread::hardware_concurrency ();
68
107
assert (availableCores > 0 );
69
108
return availableCores;
70
109
}
71
110
72
111
private:
73
- std::thread m_thread ;
112
+ std::jthread m_jthread ;
74
113
std::atomic_bool m_running{false };
75
114
std::mutex m_mutex;
76
- std::condition_variable m_condition;
77
115
Task m_task;
78
116
};
0 commit comments