thread库使用摘要

和智能指针一样,thread库也已经被加入到标准了,为了照顾某些不是最新版本的C++编译器,这里还是以boost中的thread为例,其和标准thread几乎一样。

1. build使用boost::thread的代码时,要链接libboost_thread.so和libboost_systrem.so,注意确认库文件名,有时是libboost_thread-mt.so和libboost_systrem-mt.so

2. thread对象是不可拷贝的。如果需要将其放入容器中,一般采用两种方法:(1)使用move语义;(2)初始化一个指向它的智能指针,容器中保存智能指针

3. 线程睡眠

     boost::this_thread::sleep(boost::posix_time::seconds(2)); // 本线程睡眠2秒钟

4. 使用boost::mutex的lock和unlock方法时,要加上try-catch,确保顺利unlock

   // 由于临界区可能抛出异常,为了保证unlock被调用,要加上try-catch
   boost::mutex mu;
   try {
       mu.lock();
       std::cout << "critical section" << std::endl; // 临界区
       mu.unlock();
   } catch(...) {
       mu.unlock();
   }

5. 优先使用scoped_lock,让加锁和解锁自动化

   // 使用大括号,构造出一个作用域,将需要锁保护的操作放入其中,使用自动锁保护
   {
        boost::mutex mu;
        // 构造自动锁对象,在构造函数中完成加锁操作
        // 当退出作用域后,自动锁的析构函数被调用,在析构函数中完成解锁操作
        boost::mutex::scoped_lock lock(mu);
        std::cout << "critical section" << std::endl; // 临界区
   }

6. 创建线程

   void print_func(int x, const std::string& s) {
       std::cout << x << std::endl;
       std::cout << s << std::endl;
   }
  
   int x = 8;
   std::string s("Hello, world")
   
   boost::thread print_thread(print_func, x, s);

7. 线程等待

   print_thread.join(); // 等待线程print_thread执行完毕才返回
   print_thread.timed_join(boost::posix_time::secodes(10)); // 最多等待线程print_thread执行10秒,可以提前返回

8. 中断线程

    print_thread.interrupt();

9. 设置中断点

   boost::this_thread::interruption_point();

10. 启用/禁用中断

   boost::this_thread::interruption_enabled(); // 检测当前线程是否允许被中断
   boost::this_thread::disable_interruption类,其对象具有RAII性质,构造时禁用中断,析构时自动恢复
   boost::this_thread::restore_interruption类,构造时启用中断,析构时禁用中断

   {
       boost::this_thread::disable_interruption di; // 禁用中断
       // do sth
       boost::this_thread::interruption_point();    // 中断被禁用,中断点无效
       boost::this_thread::restore_interruption ri(di); // 启用中断
       // do sth
       boost::this_thread::interruption_point();    // 中断点有效,线程被中断
       // do sth, but we never get here
   }

11. 条件变量优先使用condition_variable_any,它能够适应更广泛的互斥量类型。boost库有个typedef,typedef boost::condition_variable_any boost::condition,所以可以直接使用boost::condition

12. 条件变量使用示例:

    // 生产者线程和消费者线程均可访问到的全局变量(相对于它们而言)
    boost::mutex mu;
    boost::condition_variable_any condi; // 等价于boost::condition condi;
    std::queue<std::string> q;

    // 消费者线程,q为队列
   {
        boost::mutex::scoped_lock lock(mu);
        while (q.empty()) {
            condi.wait(mu);
        }

        std::string s = q.front();
        std::cout << s << std::endl;
   }

   // 生产者线程
   {
       boost::mutex::scoped_lock lock(mu);
       std::string s("abc");
       q.push(s);
       condi.notify_one();
   }

13. 读写锁shared_mutex

         boost::shared_mutex sm;
    // 读锁定
    {
        boost::shared_lock<boost::shared_mutex> sl(sm);
        // do sth
    }


    // 写锁定
    {
        boost::unique_lock<boost::shared_mutex> ul(sm);
        // do sth
    }

14. 仅初始化一次

    static int g_count;
    void init_func() {
        std::cout << "This init_func function should be called only once" << std::endl;
        g_count = 8;
    }

    void init_func() {
        std::cout << "This init_func function should be called only once" << std::endl;
        g_count = 8;
    }

    boost::once_flag of = BOOST_ONCE_INIT;
    void call_func() {
        call_once(of, init_func);
    }

    int main() {
        boost::thread t1(call_func);
        boost::thread t2(call_func);
        boost::thread t3(call_func);

        t1.join();
        t2.join();
        t3.join();

        return 0;
    }

15. cout等流对象在多线程环境下要加锁,它们不是线程安全的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值