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
{
35
+ if (m_jthread.joinable ()) {
36
+ return false ;
37
+ }
38
+
26
39
m_running.store (true );
27
- m_thread = std::thread ([this ]() {
28
- m_condition.notify_one ();
29
- if (m_task) {
30
- m_task ();
40
+ m_jthread = std::jthread ([this ](std::stop_token token) {
41
+ {
42
+ std::unique_lock<std::mutex> lock (m_mutex);
43
+ if (m_task) {
44
+ try {
45
+ m_task (token);
46
+ } catch (const std::exception &e) {
47
+ std::cerr << " Thread exception: " << e.what () << std::endl;
48
+ }
49
+ }
31
50
}
51
+
52
+ m_running.store (false );
53
+ m_running.notify_all ();
32
54
});
55
+
56
+ return true ;
33
57
}
34
58
35
59
void stop ()
36
60
{
37
- if (m_thread.joinable ()) {
38
- m_thread.join ();
61
+ if (m_jthread.joinable ()) {
62
+ m_jthread.request_stop ();
63
+ m_jthread.join ();
39
64
}
65
+
40
66
m_running.store (false );
41
67
}
42
68
43
- void waitForStarted ()
69
+ void interrupt ()
44
70
{
45
- std::unique_lock<std::mutex> lock (m_mutex);
46
- m_condition.wait (lock, [this ]() { return m_running.load (); });
71
+ if (m_jthread.joinable ()) {
72
+ m_jthread.request_stop ();
73
+ }
74
+ }
75
+
76
+ void waitForFinished ()
77
+ {
78
+ while (m_running.load ()) {
79
+ m_running.wait (true );
80
+ }
47
81
}
48
82
49
- [[nodiscard]] auto isRunning () const -> bool { return m_running; }
83
+ [[nodiscard]] bool isRunning () const { return m_running. load () ; }
50
84
51
- [[nodiscard]] auto getThreadId () const -> std::thread::id { return m_thread .get_id (); }
85
+ [[nodiscard]] std::thread::id getThreadId () const { return m_jthread .get_id (); }
52
86
53
87
static void yield () { std::this_thread::yield (); }
54
88
@@ -64,15 +98,14 @@ class Thread : noncopyable
64
98
65
99
static auto hardwareConcurrency () -> unsigned int
66
100
{
67
- auto availableCores = std::thread::hardware_concurrency (); // 如果不支持,返回0
101
+ auto availableCores = std::thread::hardware_concurrency ();
68
102
assert (availableCores > 0 );
69
103
return availableCores;
70
104
}
71
105
72
106
private:
73
- std::thread m_thread ;
107
+ std::jthread m_jthread ;
74
108
std::atomic_bool m_running{false };
75
109
std::mutex m_mutex;
76
- std::condition_variable m_condition;
77
110
Task m_task;
78
111
};
0 commit comments