Ceph是一款优秀的分布式存储软件,通过学习它的源码,我们可以学到很多编程技巧,ceph中关于多线程的编程,是一个很好的学习对象。
Ceph中线程的在src/common/Thread.h中定义
class Thread {
private:
pthread_t thread_id;
public:
Thread(const Thread& other);
const Thread& operator=(const Thread& other);
Thread();
virtual ~Thread();
protected:
virtual void *entry() = 0;//子类需要实现此函数,作为线程入口
private:
static void *_entry_func(void *arg);
public:
const pthread_t &get_thread_id();
bool is_started();
bool am_self();
int kill(int signal);//杀掉自己
int try_create(size_t stacksize);
void create(size_t stacksize = 0);//创建线程,里面传入了entry函数
int join(void **prval = 0);//阻塞自己等待线程结束,回收资源
int detach();//父子线程分离
};
C开发者都知道线程编程接口,一个线程在创建时调用pthread_create函数来传入entry函数,杀死线程调用pthread_kill函数,当线程被杀死之后,必须调用pthread_join函数来进行线程资源的回收,如果不调用此函数,就会出现类似zombie process。如果要想让系统自己回收线程资源,就要将线程与父线程分离即调用pthread_detach.通过接口对比,我们发现src/common/Thread.h中定义的class thread,实际上是对线程代码ceph自己实现的一层封装。
Ceph中所有要用的线程必须继承Thread类,通过查找发现如下一些线程:
Accepter.h (src\msg):class Accepter : public Thread //用来socket bind的线程, accepter线程入口函数里定义了poll的网络通讯结构,用来放入管道
Admin_socket.h (src\common):class AdminSocket : public Thread
Ceph_context.cc (src\common):class CephContextServiceThread : public Thread
DispatchQueue.h (src\msg): class DispatchThread : public Thread //用来进行消息分发的线程, 在simpleMessenger中有dispatch_queue成员变量,
FileJournal.h (src\os): class Writer : public Thread //用来进行写数据到journal中的线程
FileJournal.h (src\os): class WriteFinisher : public Thread //当用aio异步模式写数据到journal完成后,此线程用来接管其他剩余操作
FileStore.h (src\os): struct SyncThread : public Thread //用来同步数据执行同步的线程,主要是将已经完成的journal的序列号写入到文件中
Finisher.h (src\common): struct