//CurrentThread,定义了一些辅助函数
namespace muduo
{
namespace CurrentThread
{
// internal
extern __thread int t_cachedTid;
extern __thread char t_tidString[32];
extern __thread int t_tidStringLength;
extern __thread const char* t_threadName;
void cacheTid();
inline int tid()
{
if (__builtin_expect(t_cachedTid == 0, 0))
{
cacheTid();
}
return t_cachedTid;
}
inline const char* tidString() // for logging
{
return t_tidString;
}
inline int tidStringLength() // for logging
{
return t_tidStringLength;
}
inline const char* name()
{
return t_threadName;
}
bool isMainThread();
void sleepUsec(int64_t usec);
}
}
//Thread.h&&cpp
namespace muduo
{
//线程对象
//主线程开启一个在新线程的工作,代表这个新线程的对象就是Thread,它很显然留在了主线程,而在
//它的start()里,显然需要完成以下任务:计算自己的线程id,线程名,保存所属主线程,运行主线程传递来的func
class Thread : noncopyable
{
public:
typedef std::function<void ()> ThreadFunc;//线程工作函数类型
explicit Thread(ThreadFunc, const string& name = string());//这里更新,以前用的是ThreadFunc&,现在是拷贝然后move
// FIXME: make it movable in C++11
~Thread();
void start();
int join(); // return pthread_join()
bool started() const { return started_; }
// pthread_t pthreadId() const { return pthreadId_; }
pid_t tid() const { return tid_; }//返回线程的系统id
const string& name() const { return name_; }
static int numCreated() { return numCreated_.get(); }
private:
void setDefaultName();//在线程的构造函数里使用
bool started_;
bool joined_;
pthread_t pthreadId_;//同一进程里的不同线程号,用于区分线程,回收后可重复使用
pid_t tid_;//内核里的线程/进程id
ThreadFunc func_;//工作函数
string name_;
CountDownLatch latch_;//计数器,C++17版新增
static AtomicInt32 numCreated_;
};
}
namespace muduo
{
namespace CurrentThread//线程局部变量
{
__thread int t_cachedTid = 0;//pid_t就是int
__thread char t_tidString[32];
__thread int t_tidStringLength = 6;
__thread const char* t_threadName = "unknown";
static_assert(std::is_same<int, pid_t>::value, "pid_t should be int");//让编译器检查int和pid_t是同类型
}
namespace detail
{
//::syscall(SYS_gettid)得到线程id
pid_t gettid()
{
return static_cast<pid_t>(::syscall(SYS_gettid));
}
//fork之后 先将t_cachedTid = 0,改线程名,调用函数重新计算tid
void afterFork()
{
muduo::CurrentThread::t_cachedTid = 0;
muduo::CurrentThread::t_threadName = "main";
CurrentThread::tid();
// no need to call pthread_atfork(NULL, NULL, &afterFork);
}
//有了这个类
class ThreadNameInitializer
{
public:
ThreadNameInitializer()
{
muduo::CurrentThread::t_threadName = "main";
CurrentThread::tid();
//#include <pthread.h>
//int pthread_atfork(void(*prepare)(void), void(*parent)(void), void(*child)(void));
//pthread_atfork()在fork()之前调用,当调用fork时,内部创建子进程前在父进程中会调用prepare,
//内部创建子进程成功后,父进程会调用parent ,子进程会调用child。
pthread_atfork(NULL, NULL, &afterFork);//相当于给子进程的回掉函数
}
};
ThreadNameInitializer init;//全局变量,初始化就为主线程生成线程信息
//线程数据,线程A将它传送到新开启的线程B,然后A调用函数startThread开启B线程任务,B更新线程信息后执行A传递的func
struct ThreadData
{
typedef muduo::Thread::ThreadFunc ThreadFunc;
ThreadFunc func_;
string name_;
pid_t* tid_;
CountDownLatch* latch_;
ThreadData(ThreadFunc func,
const string& name,
pid_t* tid,
CountDownLatch* latch)
: func_(std::move(func)),
name_(name),
tid_(tid),
latch_(latch)
{ }
//ThreadData具体的执行
void runInThread()
{
*tid_ = muduo::CurrentThread::tid();//计算本线程id,保存在线程局部变量里
tid_ = NULL;//然后。。。没用了
latch_->countDown();// latch_是主线程传递过来的,主线程等待从线程减少技术
latch_ = NULL;//没用了
muduo::CurrentThread::t_threadName = name_.empty() ? "muduoThread" : name_.c_str();
::prctl(PR_SET_NAME, muduo::CurrentThread::t_threadName);
try
{
func_();
muduo::CurrentThread::t_threadName = "finished";
}
catch (const Exception& ex)
{
muduo::CurrentThread::t_threadName = "crashed";
fprintf(stderr, "exception caught in Thread %s\n", name_.c_str());
fprintf(stderr, "reason: %s\n", ex.what());
fprintf(stderr, "stack trace: %s\n", ex.stackTrace());
abort();
}
catch (const std::exception& ex)
{
muduo::CurrentThread::t_threadName = "crashed";
fprintf(stderr, "exception caught in Thread %s\n", name_.c_str());
fprintf(stderr, "reason: %s\n", ex.what());
abort();
}
catch (...)
{
muduo::CurrentThread::t_threadName = "crashed";
fprintf(stderr, "unknown exception caught in Thread %s\n", name_.c_str());
throw; // rethrow
}
}
};
//父线程交给系统的回调,obj是父线程传递的threadData
void* startThread(void* obj)
{
ThreadData* data = static_cast<ThreadData*>(obj);
data->runInThread();
delete data;
return NULL;
}
}
}
using namespace muduo;
void CurrentThread::cacheTid()
{
if (t_cachedTid == 0)//为0说明是新线程
{
t_cachedTid = detail::gettid();
t_tidStringLength = snprintf(t_tidString, sizeof t_tidString, "%5d ", t_cachedTid);
}
}
bool CurrentThread::isMainThread()
{
return tid() == ::getpid();
}
void CurrentThread::sleepUsec(int64_t usec)
{
struct timespec ts = { 0, 0 };//秒+纳秒
//s,ms,us,ns都是1:1000
ts.tv_sec = static_cast<time_t>(usec / Timestamp::kMicroSecondsPerSecond);// us/1000000
ts.tv_nsec = static_cast<long>(usec % Timestamp::kMicroSecondsPerSecond * 1000);//%取秒之后的数,再转化成us
::nanosleep(&ts, NULL);
}
AtomicInt32 Thread::numCreated_;//这是静态变量
Thread::Thread(ThreadFunc func, const string& n)
: started_(false),
joined_(false),
pthreadId_(0),
tid_(0),
func_(std::move(func)),//forC++17
name_(n),
latch_(1)
{
setDefaultName();
}
Thread::~Thread()
{
if (started_ && !joined_)
{
pthread_detach(pthreadId_);//pthreadId_就是这个作用了
}
}
void Thread::setDefaultName()
{
int num = numCreated_.incrementAndGet();
if (name_.empty())
{
char buf[32];
snprintf(buf, sizeof buf, "Thread%d", num);
name_ = buf;
}
}
void Thread::start()
{
assert(!started_);
started_ = true;
// FIXME: move(func_)
detail::ThreadData* data = new detail::ThreadData(func_, name_, &tid_, &latch_);
if (pthread_create(&pthreadId_, NULL, &detail::startThread, data))//如果开启失败
{
started_ = false;
delete data; // or no delete?
LOG_SYSFATAL << "Failed in pthread_create";
}
else
{
latch_.wait();
assert(tid_ > 0);
}//子线程已经开始运行了~~
}
int Thread::join()
{
assert(started_);
assert(!joined_);
joined_ = true;
return pthread_join(pthreadId_, NULL);//pthreadId_,
}