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