【学习点滴】boost库的一点知识

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

boost::thread_specific_ptr

今天看代码发现用到了boost库的thread_specific_ptr,就在网上搜了下

    线程私有变量(Thread Local Storage)之于线程相当于静态变量之于进程,与进程变量相比是每个线程都有一份, 也就是所谓的“私有”。也可以把线程私有变量理解为key-value对,其中key是线程ID。它的主要作用是在多线程编程中避免锁竞争的开销。其多种实现及原理可见:https://spockwangs.github.io/blog/2017/12/01/thread-local-storage/   本文主要看Boost的TLS实现

    大多数函数都不是可重入的。这也就是说在某一个线程已经调用了一个函数时,如果你再调用同一个函数,那么这样是不安全的。一个不可重入的函数通过连续的调用来保存静态变量或者是返回一个指向静态数据的指针。

    举例来说,std::strtok就是不可重入的,因为它使用静态变量来保存要被分割成符号的字符串。有两种方法可以让不可重用的函数变成可重用的函数。第一种方法就是改变接口,用指针或引用代替原先使用静态数据的地方。比方说,POSIX定义了strok_r,std::strtok中的一个可重入的变量,它用一个额外的char**参数来代替静态数据。这种方法很简单,而且提供了可能的最佳效果。但是这样必须改变公共接口,也就意味着必须改代码。另一种方法不用改变公有接口,而是用本地存储线程(thread local storage)来代替静态数据(有时也被成为特殊线程存储,thread-specific storage)。

     Boost线程库提供了智能指针boost::thread_specific_ptr来访问本地存储线程。每一个线程第一次使用这个智能指针的实例时,它的初值是NULL,所以必须要先检查这个它的只是否为空,并且为它赋值。Boost线程库保证本地存储线程中保存的数据会在线程结束后被清除。

      下方是一个使用boost::thread_specific_ptr的简单例子。其中创建了两个线程来初始化本地存储线程,并有10次循环,每一次都会增加智能指针指向的值,并将其输出到std::cout上(由于std::cout是一个共享资源,所以通过互斥体进行同步)。main线程等待这两个线程结束后就退出。从这个例子输出可以明白的看出每个线程都处理属于自己的数据实例,尽管它们都是使用同一个boost::thread_specific_ptr。

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/tss.hpp>
#include <iostream>
 
boost::mutex io_mutex;
boost::thread_specific_ptr<int> ptr;
 
struct count
{
        count(int id) : id(id) { }
        
        void operator()()
        {
                if (ptr.get() == 0)
                ptr.reset(new int(0));
                
                for (int i = 0; i < 10; ++i)
                {
                        (*ptr)++;
                        boost::mutex::scoped_lock
                        lock(io_mutex);
                        std::cout << id << ": "
                        << *ptr << std::endl;
                }
        }
        
        int id;
};
 
int main(int argc, char* argv[])
{
        boost::thread thrd1(count(1));
        boost::thread thrd2(count(2));
        thrd1.join();
        thrd2.join();
        return 0;
}

 

 

boost::split

拆分字符串的,直接上例子

#include <boost/algorithm/string.hpp>
#include <iostream>
#include <string>
#include <vector>
using namespace boost::algorithm;
using namespace std;
int main(){
    string str("miss,you.just.call_to,say,I~love~you");
    vector<string> strVec;
    split(strVec, str, is_any_of(",."));
    vector<string>::iterator it = strVec.begin();
    for (; it!=strVec.end(); it++){
        cout << *it << endl;
    }
    return 0;
}

运行的结果就是都拆出来了  miss you  just  call to  say   I~love~you,  注意分隔符是 , .  没有用~,  所有后面的I~love~you没有拆

头文件统一的话就用的#include<boost/algorithm/string.hpp>    9, 10行就是split的使用方式

 

boost::mutex::scoped_lock

区域锁boost::mutex::scoped_lock顾名思义就是在作用域内有效,当离开作用域自动释放锁,传递参数是锁

区域锁就是把锁封装到一个对象里面。锁的初始化放到构造函数,锁的释放放到析构函数。这样当锁离开作用域时,

析构函数会自动释放锁。即使运行时抛出异常,由于析构函数仍然会自动运行,所以锁仍然能自动释放。一个典型的区域锁

void CSettingCenter::ClearPlatformServiceInfoCache()

{

boost::mutex::scoped_lock lock(m_mutexAccessServiceManager);

m_mapAccessServiceManager.clear();

}

 

应用于有大量的return返回的代码,避免出现死锁的问题

 

 

 

boost::function 与 boost::bind

boost::bind 是std::bindlist 和 std::bind2nd的结合体。它提供一个任意的函数对象(仿函数)、函数、函数指针、成员函数指针。 它可以绑定任意的参数。bind 没有对函数对象有任何的要求。

void print(int array[], int size)
{
  for (int i = 0; i < size; i++) {
    printf("%d\n", array[i]);
  }
}

int main(int argc, const char *argv[])
{
  int array[]= {1,2,1,34,5,5,56,9,6,10};
  int len = sizeof(array)/sizeof(array[0]);
  // 绑定普通函数

  boost::bind(print, _1,_2)(array, len);
  // 与function结合

  boost::function<void(int [], int)> fn = boost::bind(print, _1,_2);
  fn(array, len);  return  0;
}

 

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <stdio.h>
#include <string>
#include <map>

class SimpleLineReader {
public:
  SimpleLineReader (const string& filename)
  {
    fp_ = fopen(filename.c_str(), "r");
  }
  ~SimpleLineReader (){
    if (fp_) {
      fclose(fp_);
    }
  }
  typedef boost::function<bool (const std::string& line)> Callback;    // here
  bool ProcessLines(Callback fn)
  {
    if (!fp_)
    {
      return false;
    }
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    while ((read = getline(&line, &len, fp_)) != -1) {
      string str(line, read);
      fn(line);
    }
    free(line);
    return true;
  }
private:
    FILE* fp_;
};

class CityLoader {
public:
  CityLoader (){}
  int init(const std::string& filename)
  {
    SimpleLineReader reader(filename);
    reader.ProcessLines(boost::bind(&CityLoader::ProcessLine, this, _1));     // here
    printf("readline\t%d\n", city_map_.size());
  }
  ~CityLoader ()
  {
  }
private:
  bool ProcessLine(const std::string& line)
  {
    static int cnt = 0;
    if (line.empty())
    {
      return true;
    }
    city_map_.insert(make_pair(++cnt, line));
    return true;
  }
  std::map<int, std::string> city_map_;
};
void test_simple_line_reader()
{
  CityLoader city_loader;
  city_loader.init("data/city.txt");
}
int main()
{
    test_simple_line_reader();
}

注意 function<void(void)>

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>

typedef boost::function<void(void)>Func;

void print_string(const std::string s)
{
    std::cout<<"s:"<<s<<std::endl;
}

int main()
{
    Func f(boost::bind(print_string,"hello bind"));
    f();
    return 0;
}

 

 

 

BOOST 在深度学习中的应用及代码分析 BOOST 是一个经过广泛测试、开源且跨平台的 C++ 集合,它起始于 1998 年,旨在填补 C++ 标准的一些不足,并提供更高级的编程抽象。容器与数据结构:像提供了多维数组支持,方便处理图像、张量等深度学习中的数据结构,相比原生 C++ 数组,它具有更丰富的操作接口和边界检查等功能。算法命名空间下有大量字符串处理、查找等实用算法,在数据预处理阶段,可用于文本数据的清洗、特征提取等任务。数学与数值计算。 阅读详情

相关推荐

boost学习之路

boost使用介绍安装步骤测试智能指针scoped_ptrscoped_arrayshared_ptrshared_arrayweak_ptr进程之间的通信 介绍 Boost是一个可移植、提供源代码的C++,作为标准的后备,是C++标准化进程的开发引擎之一。 Boost由C++标准委员会工作组成员发起,其中有些内容有望成为下一代C++标准内容。在C++社区中影响甚大,是不折不扣的“准”标准Boost由于其对跨平台的强调,对标准C++的强调,与编写平台无关。 安装 步骤 1.下载 https

qq_35581213的博客 996

【C/C++】BOOST 线程完全攻略 - 基础篇

C++多线程开发是一个复杂的事情,mfc下提供了CWinThread类,和AfxBeginThread等等函数,但是在使用中会遇到很多麻烦事情,例如线程之间参数传递的问题,我们一般都是把参数new一个结构体,传递给子线程,然后释放的工作交给了子线程,这样不可避免会有内存泄漏的危险,例如线程关闭的问题,我们一般用WaitForSingleObject来完成线程关闭工作,但是这个函数并不一定保证线程能

ZhangPY的专栏 6034

C++11的新功能特性对Boost影响

Boost程序探秘——深度解析C++准标准》之试读         前一阵子还看到一篇文章,说C#要重蹈C++的覆辙,这里说的C++的覆辙是什么呢?是指C++语言过于臃肿的功能特性,导致学习人员的流失。文章说,语言最后的威力是“开发软件”,而不是“比拼新特性”        在大学中,C++算是比较难学的语言。有些学校试图直接让学生们学习C++,结果效果不怎么好。这次,C++11又添

sunny2038的专栏 2万+

boost中thread多线程中的thread_specific_ptr

大多数函数都不是可重入的。这也就是说在某一个线程已经调用了一个函数时,如果你再调用同一个函数,那么这样是不安全的。举例来说,std::strtok就是不可重入的,因为它使用静态变量来保存要被分割成符号的字符串。 一个不可重入的函数通过连续的调用来保存静态变量或者是返回一个指向静态数据的指针,有两种方法可以让不可重用的函数变成可重用的函数。 方法1:就是...

sunlin972913894的博客 1453

Boostboost中thread多线程详解9——thread_specific_ptr线程局部存储

大多数函数都不是可重入的。这也就是说在某一个线程已经调用了一个函数时,如果你再调用同一个函数,那么这样是不安全的。一个不可重入的函数通过连续的调用来保存静态变量或者是返回一个指向静态数据的指针。 举例来说,std::strtok就是不可重入的,因为它使用静态变量来保存要被分割成符号的字符串。有两种方法可以让不可重用的函数变成可重用的函数。第一种方法就是改变接口,用指针或引用代替原先使用静态数据的地

liujiayu2的专栏 6465

boost::thread_specific_ptr

thread_specific_ptr代表了一个全局的变量,而在每个线程中都各自new一个线程本地的对象交给它进行管理。 线程之间就不会因为访问同一全局对象而引起资源竞争导致性能下降。 而线程结束时,这个资源会被自动释放。 #include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp...

dianyun7150的博客 200

C++小品:井水不犯河水的thread_specific_ptr,C++11线程中的本地存储

thread_specific_ptr 定义了一个跟线程相关的存储接口。实际上,它就是对TLS  Thread-Locally Storage的包装。它可用于封装线程独立的全局变量。 其作用和使用方法有点类似于shared_ptr。 在每个线程中,都各自new一个对象交给全局的threah_specific_ptr进行管理,当线程退出后,他会自动释放这个对象,这一点与shared_

flyingleo1981的专栏 6149

C++ Boost:windows下编译Boost

文章目录1. 需要编译的boost2. 编译步骤3. 命名规则4. VS配置目录 1. 需要编译的boost 通过bjam --show-libraries查看那些需要编译: D:\Project\VisualStudioProjects\boost_1_67_0>bjam --show-libraries The following libraries require building: - atomic - chrono - container - con

超级大洋葱的博客 1万+

linux下boost的安装

boost‘准标准’安装过程。 系统是ubuntu虚拟机,安装的是boost_1_60_0。 (1)首先去下载最新的boost代码包,网址www.boost.org。 (2)进入到自己的目录,解压: bzip2 -d boost_1_60_0.tar.bz2 tar xvf boost_1_60_0.tar (3)之后进入boost目录 cd boost_1_60_0/ ./bootstrap...

Patrick的博客 3213

Windows 11 安装Boost

在C++中,函数对象(又称为functors)是一种行为类似函数的对象。它们是一种通过类的实例来模拟函数的功能的方式。优点:相比于普通函数,它可以包含局部状态信息。

zhouzhiwengang的专栏 7811

Boost C++ 学习手册(一)

原文:zh.annas-archive.org/md5/9ADEA77D24CFF2D20B546F835360FD23 译者:飞龙 协议:CC BY-NC-SA 4.0 前言 Boost 不仅仅是一组有用的、可移植的、通用的 C++。它还是一个重要的孵化器,其中的想法和概念会成为 ISO C++标准本身的一部分。如果您参与编写 C++软件的开发,学习使用 Boost 将使您免于重复发明轮子,提高软件质量,并很可能提高您的生产力。 十年前,我第一次接触到 Boost ,当时我正在寻找一个可移植的

龙哥盟 3750

BOOST C++BOOST C++20个分类指南

我们强调与 C++ 标准配合良好的Boost 旨在广泛使用,并可用于广泛的应用程序。 Boost 许可证鼓励所有用户以最少的限制使用 Boost

gongdiwudu的专栏 5985

学习boost手册

学习boost手册: 在线学习:http://zh.highscore.de/cpp/boost/

bible521125的专栏 6225

boost 的函数式编程 Phoenix入门学习

这篇文章是我学习boost phoenix的总结。 序言 Phoenix是一个C++的函数式编程(function programming)。Phoenix的函数式编程是构建在函数对象上的。因此,了解Phoenix,必须先从它的基础函数对象上做起。 Phoenix能够提供令人惊艳的编码效果。我先撂一个出来,看看用Phoenix能写出什么样的代码: std::for_e

doon的专栏 5398

Boost程序入门学习_boost学习

我们可以看到:头文件安装到了/usr/local/include,文件安装到/usr/local/lib中。Boost大多数组件不需要编译链接,在自己的源码中直接包含头文件即可。文件后缀.hpp = .h + .cpp,把C++类的声明和实现放在了一个文件中。剩下的少量(如thread,date_time)必须编译成静态或者动态,并在构建时指定链接选项。

2501_90251128的博客 618

BOOST 中filesyatem 学习

boostfilesystem的学习

luguifang2011的专栏 2109

Linux下使用CMake进行编译的时候寻找Boost

Linux下使用CMake进行编译的时候寻找Boost find_package 通过调用find_package可以找到头文件和所需要的文件或者是一个CMake打包配置文件, find_package(Boost [version] [EXACT] # 可选项,最小版本或者确切所需版本 [REQUIRED] # 可选项,如果找不到所需,报错 [COMPONENTS <libs>...] # 所需的名称,比如说. "date_t.

hyl999的专栏 4384

一文详解C++的Boost

Boost 是 C++ 领域最具影响力的开源集合之一,被誉为 “C++ 标准的试验场和扩展”。它由全球数千名开发者协作维护,包含超过 160 个独立,覆盖从基础数据结构到高级网络编程、并发控制、数学计算等几乎所有 C++ 开发场景。

weixin_41413777的博客 1961
上一篇: 【学习点滴】cpp遇到的一些疑问和积累
下一篇: 【学习点滴】c++ 三个线程循环打印ABC
o小菜
博客等级 码龄9年 25粉丝 54原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值