线程模块:

  • 成员变量m_thread:线程id(进程中唯一)
  • 成员变量pid_t:线程id(Linux系统中唯一)
  • 成员变量function<void()> m_cb:线程执行的函数
  • 成员变量string:线程名
  • 线程周期变量thread_local Thread* t_thread:当前线程对应的类的指针
  • 线程周期变量thread_local ``std::string t_thread_name:当前线程对应的线程名

线程类实例化时传入执行的函数以及线程名,在构造函数中调用run静态成员方法,该方法会给线程周期变量进行赋值,并调用传入的函数。

  • 静态函数run中,存在cb.swap()函数
    • 生命周期:将thread类中转移局部变量m_cb,保证函数执行完成后自动销毁
    • 防止重复执行:避免回调过程中对thread->m_cb进行错误重复执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Thread {
public:
typedef std::shared_ptr<Thread> ptr;
Thread(std::function<void()> cb, const std::string& name);
~Thread();

pid_t getId() const { return m_id; }
const std::string& getName() const { return m_name; }

void join();

static Thread* GetThis();
static const std::string& GetName();
static void SetName(const std::string& name);
private:
Thread(const Thread&) = delete;
Thread(const Thread&&) = delete;
Thread operator=(const Thread&) = delete;

static void* run(void* arg);
private:
pid_t m_id;
pthread_t m_thread = 0;
std::function<void()> m_cb;
std::string m_name;

Semaphore m_semaphore;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "thread.h"
#include "log.h"
#include "util.h"
namespace sylar {
static thread_local Thread* t_thread = nullptr;
static thread_local std::string t_thread_name = "UNKNOW";

static sylar::Logger::ptr g_logger = SYLAR_LOG_NAME("system");

Thread* Thread::GetThis() {
return t_thread;
}

const std::string& Thread::GetName() {
return t_thread_name;
}

void Thread::SetName(const std::string& name) {
if (name.empty()) {
return;
}
if (t_thread) {
t_thread->m_name = name;
}
t_thread_name = name;
}

Thread::Thread(std::function<void()> cb, const std::string& name)
: m_cb(cb)
, m_name(name) {
if (name.empty()) {
m_name = "UNKNOW";
}
int rt = pthread_create(&m_thread, nullptr, &Thread::run, this);
if (rt) {
SYLAR_LOG_ERROR(g_logger) << "pthread_create thread fail, rt=" << rt << " name=" << name;
throw std::logic_error("pthread_create error");
}
m_semaphore.wait();
}

Thread::~Thread() {
if (m_thread) {
pthread_detach(m_thread);
}
}

void Thread::join() {
if (m_thread) {
int rt = pthread_join(m_thread, nullptr);
if (rt) {
SYLAR_LOG_ERROR(g_logger) << "pthread_join thread fail, rt=" << rt << " name=" << m_name;
}
}
m_thread = 0;
}

void* Thread::run(void* arg) {
Thread* thread = (Thread*)arg;
t_thread = thread;
t_thread_name = thread->m_name;
thread->m_id = sylar::GetThreadId();
pthread_setname_np(pthread_self(), thread->m_name.substr(0, 15).c_str());

std::function<void()> cb;
cb.swap(thread->m_cb);

t_thread->m_semaphore.notify();

cb();
return 0;
}

}