Sylar服务器框架——线程模块

1、该模块比较简单,提供了线程类和线程同步类,需要注意的是,线程类的构造函数传入线程入口函数和线程名称,线程入口函数类型为void(),如果带参数,则需要用std::bind进行绑定。线程类构造之后线程即开始运行,构造函数在线程真正开始运行之后返回,为了实现这一需求使用了信号量,Thread::run函数代码如下,其中有两个值得学习的地方,一是swap,二是信号量:

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());
    // 这里的swap可以防止线程执行函数的时候,其他的线程对thread->m_cb进行操作,造成危险的行为
    std::function<void()> cb;
    cb.swap(thread->m_cb);
    // 这里的信号量保证线程函数跑起来后,再出构造函数
    thread->m_semaphore.notify();

    cb();
    return 0;
}

2、线程同步类被封装到mutex.h文件中,包含下面几个类:

  • Semaphore: 计数信号量,基于sem_t实现
  • Mutex: 互斥锁,基于pthread_mutex_t实现
  • RWMutex: 读写锁,基于pthread_rwlock_t实现
  • Spinlock: 自旋锁,基于pthread_spinlock_t实现
  • CASLock: 原子锁,基于std::atomic_flag实现
    3、本模块需要注意的点:
  • 为什么不直接使用C++11提供的thread类。按sylar的描述,因为thread其实也是基于pthread实现的。并且C++11里面没有提供读写互斥量,RWMutex,Spinlock等,在高并发场景,这些对象是经常需要用到的,所以选择自己封装pthread。
  • 关于线程入口函数。sylar的线程只支持void(void)类型的入口函数,不支持给线程传参数,但实际使用时可以结合std::bind来绑定参数,这样就相当于支持任何类型和数量的参数。
  • 关于子线程的执行时机。sylar的线程类可以保证在构造完成之后线程函数一定已经处于运行状态,这是通过一个信号量来实现的,构造函数在创建线程后会一直阻塞,直到线程函数运行并且通知信号量,构造函数才会返回,而构造函数一旦返回,就说明线程函数已经在执行了。
  • 关于范围锁。sylar大量使用了范围锁来实现互斥,范围锁是指用类的构造函数来加锁,用析造函数来释放锁。这种方式可以简化锁的操作,也可以避免忘记解锁导致的死锁问题,这里的思想类似RAII
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值