ceph thread源码分析

简介

在ceph中,很多任务都是用thread实现的,比如说adminsocket, log, timer等.可以说,thread是ceph中最基本的模块,因此我们的ceph源码分析从thread开始.本篇主要介绍三部分内容:

  1. thread
  2. mutex
  3. condition variable

thread

源码文件:

  1. src/common/thread.h
  2. src/common/thread.cc
class Thread
主要数据成员:
	pthread_t thread_id:  线程id
	pid_t pid: 线程pid,由linux的系统调用gettid()返回,其它系统无此系统调用,主要用于设置线程的调度优先级和cup亲和性
	int ioprio_classs, ioprio_priority: 线程的调度优先级
	int cupid: 线程的cpuid,即亲和性
	const char *thread_name: 线程名称,长度必须小于16

主要成员函数:
	create(): 相当于pthread_create,创建线程,并执行线程的启动函数 
 	join(): 相当于pthread_join, 销毁线程
 	kill(): 相当于pthread_kill

重点是线程的创建:
create(): 
	设置thread_name,并调用try_create()创建线程
try_create():
	设置线程属性,主要是线程栈的大小stacksize.
	设置线程的信号集屏蔽字.
	调用pthread_create()创建线程.即:
	pthread_create(&thread_id, thread_attr, _entry_func, (void *)this)
	线程启动函数为_entry_func, 参数为this.
entry_func():
	调用entry_wrapper()
	即(Thread *)this->entry_wrapper(),
	这里的this指针是当前对象的地址,
	如果有类继承自Thread,
	那么这里会发生多态绑定.
entry_wrapper()
	设置线程的调度优先级
	设置线程的cpu亲和性
	调用entry()执行工作
entry()
	线程类Thread是一个虚基类,entry是其唯一的纯虚函数,用于执行真正的工作.
	每个继承Thread的类都必须重新定义自己的entry()函数.

mutex

源码文件

  1. src/common/mutex.h
  2. src/common/mutex.cc
class Mutex
主要数据成员:
	string name: 互斥锁的名称
	int id: 与锁的错误检查有关
	bool recursive: // PTHREAD_MUTEX_RECURSIVE 互斥锁带递归属性
	bool lockdep: // PTHREAD_MUTEX_ERRORCHECK 互斥锁带错误检查属性
	bool backtrace: 
	pthread_mutex_t _m: 互斥锁
	int nlock: 加锁次数,为0表示没有加锁,为正表示已经加锁
	pthread_t locked_by: 加锁的线程
	CephContext *cct;
	PerfCounters *logger; 锁的统计计数
主要成员函数:
	Mutex():
		如果cct不为空,设置锁的性能统计值perfcount
		如果recursive为真,设置锁的递归属性
		如果lockdep为真,设置锁的错误检查属性
		初始化互斥锁pthread_mutex_t _m
	_post_lock():
		执行加锁之后的一些工作
		如果锁是普通锁,而不是递归锁,那么确保加锁之前nlock为0,即锁处于解锁状态,加锁之后nlock不为0,即nlock++.
		并且设置locked_by为加锁线程的pid.
	_pre_unlock():
		执行解锁之前的一些工作
		如果锁是普通锁,而不是递归锁,那么确保加锁之前nlock不为0,即锁处于加锁状态,解锁之后nlock为0,即nlock--,
		解锁之前还必须检查locked_by和当前解锁线程的pid,确保同一个线程对锁进行加锁解锁工作.
	TryLock():
		pthread_mutex_trylock()尝试加锁
		_post_lock() 善后工作
	Lock():
		pthread_mutex_lock()加锁
		_post_lock() 善后处理工作
	UnLock():
		_pre_unlock() 提前处理工作
		pthread_mutex_unlock()解锁

特别介绍:
	class Locker {
    	Mutex &mutex;
	  public:
	    explicit Locker(Mutex& m) : mutex(m) {
	      mutex.Lock();
	    }
	    ~Locker() {
	      mutex.Unlock();
	    }
	  };
	  Locker是定义于Mutex中的内部类,它在构造时执行加锁,析构时执行解锁

Mutex和Locker的比较:
共同点:
都表示互斥锁类型,用于保护共享代码区
不同点:
主要是使用地点不同前者可以用于各种简单或者复杂场合,而后者一般使用于简单的块场合中,如下例所示:

// Mutex
Mutex mutex;
mutex.lock();
do something
mutex.unlock();

// Locker
Mutex mutex;
if (cond) {
	Mutext::Locker (mutex);
	do something
}

condition variable

源码文件

  1. src/common/cond.h
class Cond
主要数据成员:
	pthread_cond_t _c: 条件变量
	Mutex *waiter_mutex: 保护条件变量的锁
主要成员函数:
	Wait():
		等待条件
		确保同一个条件变量只使用一个互访锁保护
		pthread_cond_wait()
		由于pthread_cond_wait()会先执行一次解锁操作,返回前会执行一次加锁操作,
		因此使用Mutex锁时保护条件变量时执行pthread_cond_wait()之前
		必须进行_pre_unlock(),之后必须进行_post_lock().
	
	WaitUntil():
		等待直到未来的某个时间段
		pthread_cond_timewait()

	WaitInterval():
		基于当前时间等待一段时间
		WaitUntil()

	SignalOne():
		通知某个线程条件已经发生变化
		pthread_cond_signal()

	SignalAll():
		通知所有线程条件已经发生变化
		pthread_cond_broadcast()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值