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 ; // Thread is already running
37
+ }
38
+
26
39
m_running.store (true );
27
- m_thread = std::thread ([this ]() {
40
+ m_jthread = std::jthread ([this ](std::stop_token token ) {
28
41
m_condition.notify_one ();
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 );
32
51
});
52
+
53
+ return true ; // Thread started successfully
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 ()
67
+ {
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 waitForStarted (std::optional<std::chrono::milliseconds> timeout = std::nullopt )
44
75
{
45
76
std::unique_lock<std::mutex> lock (m_mutex);
46
- m_condition.wait (lock, [this ]() { return m_running.load (); });
77
+ if (timeout.has_value ()) {
78
+ m_condition.wait_for (lock, timeout.value (), [this ]() { return m_running.load (); });
79
+ } else {
80
+ m_condition.wait (lock, [this ]() { return m_running.load (); });
81
+ }
47
82
}
48
83
49
- [[nodiscard]] auto isRunning () const -> bool { return m_running; }
84
+ [[nodiscard]] bool isRunning () const { return m_running. load () ; }
50
85
51
- [[nodiscard]] auto getThreadId () const -> std::thread::id { return m_thread .get_id (); }
86
+ [[nodiscard]] std::thread::id getThreadId () const { return m_jthread .get_id (); }
52
87
53
88
static void yield () { std::this_thread::yield (); }
54
89
@@ -64,13 +99,13 @@ class Thread : noncopyable
64
99
65
100
static auto hardwareConcurrency () -> unsigned int
66
101
{
67
- auto availableCores = std::thread::hardware_concurrency (); // 如果不支持,返回0
102
+ auto availableCores = std::thread::hardware_concurrency ();
68
103
assert (availableCores > 0 );
69
104
return availableCores;
70
105
}
71
106
72
107
private:
73
- std::thread m_thread ;
108
+ std::jthread m_jthread ;
74
109
std::atomic_bool m_running{false };
75
110
std::mutex m_mutex;
76
111
std::condition_variable m_condition;
0 commit comments