线程¶
1. 线程 Thread¶
- 成员变量
由于各个进程是相互独立的,因此不同进程的线程id可能是相同的,因此可以使用进程id来标识线程。
class Thread : boost::noncopyable { private: bool started_; // 线程是否启动 pthread_t pthreadId_; // 线程id pid_t tid_; // 独一无二的进程id ThreadFunc func_; // 线程回调函数 string name_; // 线程名 static AtomicInt32 numCreated_; // 共创建的线程个数 }; -
线程执行 在
start函数中调用pthread_crate创建线程,线程函数是startThread,然后在线程函数startThread里执行回调函数func_。由于线程入口函数是void Thread::start() { assert(!started_); started_ = true; pthread_create(&pthreadId_, NULL, &startThread, this); }static性质,想要执行回调函数runInThread,因此在传入参数时候,将线程对象本身传进入才可以在static函数中调用non-static函数。+// 实现 void* Thread::startThread(void* obj) { Thread* thread = static_cast<Thread*>(obj); thread->runInThread(); return NULL; } // 调用 pthread_create(&pthreadId_, NULL, &startThread, this);__thread关键字 这个关键字使得_thread定义的POD类型变量都是线程局部变量,即每个线程都独有一份。
2. 互斥锁 Mutex¶
MutexLock实现了对pthread_mutext_t的封装,管理mutext的生命周期,不可拷贝。-
MutexLockGuard使用RAII封装class MutexLockGuard : boost::noncopyable { public: explicit MutexLockGuard(MutexLock& mutex) : mutex_(mutex) { mutex_.lock(); } ~MutexLockGuard() { mutex_.unlock(); } private: MutexLock& mutex_; // 这里是个引用 };MutexLockGuard只是对负责mutex的lock/unlock,即不会遗忘对锁的释放而导致死锁,不负责mutex的生命周期,因此MutexLockGuard里的成员变量mutex_是**引用类型**。自动调用析构函数的解锁操作,防止死锁。3. 条件变量
Condition¶实现对
pthread_cond_t的封装,内部的mutex也是**引用类型**,即不负责生命周期。
既可以用于所有子线程等待主线程发起起跑
也可以用于主线程等待子线程初始化完毕才开始工作
-
CountDownLatch倒计时这个类利用class CountDownLatch : boost::noncopyable { public: explicit CountDownLatch(int count); void wait(); void countDown(); int getCount() const; private: mutable MutexLock mutex_; Condition condition_; int count_; };Condition实现所有线程等待某个条件产生再一起运行。具体实现依赖两个wait和countDown两个函数实现。 +mutable关键字 可以让在const修饰的函数内修改成员变量,主要即针对上面的getCount函数。