boost学习笔记

原创文章点击这里

Boost学习笔记

1 system_time

头文件:

#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

获取系统时间:

    // 注意要用unsigned int格式
    unsigned int t = boost::get_system_time().time_of_day().total_milliseconds();

延时:

    // 主线程延时
    boost::thread::sleep(boost::get_system_time() + boost::posix_time::seconds(3));
    // 子线程延时
    boost::this_thread::sleep(boost::get_system_time() + boost::posix_time::seconds(3));

获取毫秒

	const boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
	const boost::posix_time::time_duration td = now.time_of_day();
	int hh = td.hours();
	int mm = td.minutes();
	int ss = td.seconds();
	int ms = td.total_milliseconds() - ((hh * 3600 + mm * 60 + ss) * 1000)

获取并装换为字符串:

#include <boost/date_time/gregorian/gregorian.hpp>

    std::string data = boost::gregorian::to_iso_string(boost::gregorian::day_clock::local_day());

2 多线程

2.1 互斥体

2.1.1 mutex+scoped_lock
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
 
//锁住范围内的某一段代码,只被一个线程访问,其它线程被阻塞,
//退出该范围时,锁会被(析构函数)自动销毁
boost::mutex   io_mutex;
void fun(int id)
{
    //std::cout << "init" << std::endl;
    boost::mutex::scoped_lock lock(io_mutex);
    //if (lock.owns_lock())
    //    std::cout << "sucess" << std::endl;
    //else
    //    std::cout << "faile" << std::endl;
    for (int i = 0; i < 5; ++i)
    {
        std::cout << id << ": " << i << std::endl;
        boost::thread::sleep(boost::get_system_time() + boost::posix_time::seconds(1));//延时,便于观察
    }
}
 
int main()
{
    boost::thread t1(fun, 1);
    boost::thread t2(fun, 2);
    t1.join();
    t2.join();
}
2.1.2 try_mutex+scoped_try_lock
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
 
//尝试给某一段代码上锁,如果被某个线程锁住,其它线程会上锁失败,但
//会继续执行,也就是非阻塞
boost::try_mutex iomutex;
void fun(int id)
{
    boost::try_mutex::scoped_try_lock    lock(iomutex);//锁定mutex
    if (lock.owns_lock())
    {
        //std::cout << "suceess" << std::endl;
        for (int i = 0; i < 5; ++i)
        {
            std::cout << id << ": " << i << std::endl;
            boost::thread::sleep(boost::get_system_time() + boost::posix_time::seconds(1));
        }
    }
    else
    {
        //std::cout << "faile" << std::endl;
        boost::thread::yield(); //释放控制权
    }
}
 
int main()
{
    boost::thread t1(fun, 1);
    boost::thread t2(fun, 2);
    t1.join();
    t2.join();
}
2.1.3 timed_mutex+scoped_timed_mutex
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
 
//给某一段代码上锁,并设置上锁的时间;
//在上锁时间内,只有线程A访问那一段代码,其它线程阻塞;
//超过上锁时间,若线程A还在访问,则其它线程就不再等待,继续往后执行;
//超过上锁时间,若线程A已经结束访问,则其它线程再对他上锁访问;
boost::timed_mutex iomutex;
void fun(int id)
{
    boost::xtime xt;
    boost::xtime_get(&xt,boost::TIME_UTC_);
    xt.sec += 6; //设定的时间,这里单位为秒
    boost::timed_mutex::scoped_timed_lock lock(iomutex, xt); //锁定mutex
    if (lock.owns_lock())
    {
        std::cout << id << ":" << "Get lock." << std::endl;
        for (int i = 0; i < 5; ++i)
        {
            std::cout << id << ": " << i << std::endl;
            boost::thread::sleep(boost::get_system_time() + boost::posix_time::seconds(1));
        }
    }
    else
    {
        std::cout << id << ":" << "Not get lock." << std::endl;
        boost::thread::yield(); //释放控制权
    }
}
 
int main()
{
    boost::thread t1(fun, 1);
    boost::thread t2(fun, 2);
    t1.join();
    t2.join();
}
2.1.4 shared_mutex
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
 
//下面实现的是读写锁,“写独占,读共享”,写的时候一个线程占用,其它线程阻塞,读的时候所有线程一起读;
//下的main函数中还有线程池的应用,名:thread_group;
//写加锁有两种实现方式:
//    1)shr_mutex.lock();
//         shr_mutex.unlock();
//      2)boost::unique_lock<boost::shared_mutex> m(shr_mutex); //销毁时自动解锁
//读加锁有两种实现方式:
//    1)shr_mutex.lock_shared();
//         shr_mutex.unlock_shared();
//      2)boost::shared_lock<boost::shared_mutex> m(shr_mutex); //销毁时自动解锁
boost::shared_mutex shr_mutex;
 
void write_process(int id) {
    //shr_mutex.lock();
    boost::unique_lock<boost::shared_mutex> m(shr_mutex);
    for (int i = 0; i < 3; i++)
    {
        std::cout << id << ":" << i << std::endl;
        boost::thread::sleep(boost::get_system_time() + boost::posix_time::seconds(1));
    }
    //shr_mutex.unlock();
}
 
void read_process(int id) {
    boost::shared_lock<boost::shared_mutex> m(shr_mutex);
    //shr_mutex.lock_shared();
    for (int i = 0; i < 3; i++)
    {
        std::cout << id << ":" << i << std::endl;
        boost::thread::sleep(boost::get_system_time() + boost::posix_time::seconds(1));
    }
    //shr_mutex.unlock_shared();
}
 
int main() {
    boost::thread_group threads;
    for (int i = 0; i < 2; ++ i) {
        //创建两个线程用于“写”
        threads.create_thread(boost::bind(write_process, i));
        //创建两个线程用于“读”
        //threads.create_thread(boost::bind(read_process, i));
    }
    threads.join_all();
    system("pause");
    return 0;
}

2.2 条件变量

boost::condition的定义如下:

namespace boost
{
    class condition : private boost::noncopyable // Exposition only.
       // Class condition meets the NonCopyable requirement.
    {
    public:
        condition();
        ~condition();
 
        void notify_one();
//      唤起等待队列中的一个线程
        void notify_all();
//      唤起等待队列中的所有线程
        template <typename Lock> void wait(Lock& lock);
//      ScopedLock 是一个lock对象,符合ScopedLock 概念
//      释放lock中mutex上的锁,阻塞该线程,直到任何人调用了this->notify_one()或
//      this->notify_all(),然后重新lock mutex。
        template <typename Lock, typename Predicate>
            void void wait(Lock& lock, Predicate pred);
//      ScopedLock 是一个lock对象,符合ScopedLock 概念
//      相当于while (!pred()) wait(lock)。
        template <typename Lock>
            bool timed_wait(Lock& lock, const xtime& xt);
//      wait(Lock& lock)的限时版,当XT到达时,函数返回false,当因notify而返回时
//      函数返回true
        template <typename Lock, typename Predicate>
            bool timed_wait(Lock& lock, const xtime& XT, Predicate pred);
 
//      wait(Lock& lock, Predicate pred)的限时版,当XT到达时,函数返回false,当
//      因notify和pred而而返回时函数返回true
    };
};

如果定义了boost::condition cond,那么就可以用cond.wait(abc)语句让abc线程挂起,然后在另一个地方用cond.notify_one()语句把abc线程唤起,

2.3 智能指针

当多个线程同时访问某一段代码时,假如在这段代码中有指针变量*a,那么每个线程里面会有自己的“*a”变量,但变量所指向的地址是同一个,如果每个线程都执行*a++,那么最后*a的值是所有线程加的总和;如果要让每个线程的*a是私有的,就需要用到智能指针;

#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;//创建int型的智能指针
 
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()
{
        boost::thread thrd1(count(1));
        boost::thread thrd2(count(2));
        thrd1.join();
        thrd2.join();
        system("pause");
        return 0;
}

2.4 线程只运行一次

boost::call_once一般用与程序的初始化,对应的程序只被线程用一次;

#include <boost/thread/once.hpp>
 
int i = 0;
boost::once_flag flag = BOOST_ONCE_INIT;
 
void init()
{
       ++i;
}
 
void thread()
{
       boost::call_once(&init, flag);
}
 
int main(int argc, char* argv[])
{
       boost::thread thrd1(&thread);
       boost::thread thrd2(&thread);
       thrd1.join();
       thrd2.join();
       std::cout << i << std::endl;
       system("pause");
       return 0;
}

2.5 限制线程的个数

.h

#define  THREAD_NUM_ADD 0
#define  THREAD_NUM_DEL 1
 
class Mode
{
public:
    Mode();
    ~Mode();
    int m_thread_num_max = 4; // 控制的最大线程数目
    void predict();
private:
    int m_threads_num = 0;
    boost::shared_mutex shr_mutex;
    boost::thread_group threads_predict;
    boost::thread_group threads_write;
    void do_predict();
    void write_process(int i);
};

.cpp

#include "trmode.h"
 
Mode::Mode()
{
}
 
Mode::~Mode()
{
    threads_predict.join_all();
    threads_write.join_all();
}
 
void Mode::predict()
{
    //boost::function0<void> f = boost::bind(&Mode::do_predict, this);
    //boost::thread t(f);
    while (m_threads_num > m_thread_num_max); // 如果线程数目超过允许的最大数目就停留在这里
    // 线程数目加1
    threads_write.create_thread(boost::bind(&Mode::write_process, this, THREAD_NUM_ADD));
    // 创建线程
    threads_predict.create_thread(boost::bind(&Mode::do_predict, this));
}
 
void Mode::do_predict(TestDataInfo testdatainfo)
{
    // do something...
    boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(200));//延时,便于观察
    // 线程数目减1
    threads_write.create_thread(boost::bind(&Mode::write_process, this, THREAD_NUM_DEL));
}
 
void Mode::write_process(int i)
{
    boost::unique_lock<boost::shared_mutex> m(shr_mutex);
    if (i == THREAD_NUM_ADD)
        m_threads_num ++;
    else if (i == THREAD_NUM_DEL)
        m_threads_num --;
}

main.cpp

#include <trmode.h>
 
int main()
{
    Mode mode;
    for (int i = 0; i<200; i++) {
        mode.predict();
        boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(10));//延时,便于观察
    }
}

3 文件操作

需要包含的头文件:#include <boost/filesystem.hpp>
需要包含的静态库:libboost_filesystem.a

3.1 创建 path 变量

    boost::filesystem::path p1("D:\\dir"); //windows下既可使用斜杠也可使用反斜杠(资源管理器地址栏中使用的就是反斜杠),又因为在c++中反斜杠是转义字符的标志,所以使用反斜杠的话还得再加一个反斜杠
    boost::filesystem::path p2("D:/dir/data.dat"); //windows下推荐使用正斜杠
    boost::filesystem::path p3("/user/dir"); //linux下使用正斜杠
    boost::filesystem::path p4 = "./dir"; //path的构造函数没有声明为explicit,字符串可以隐式转换为path对象
 
    p1 /= "child"; //path重载了 /=,其功能与成员append()相同。
    if (p1 == p2); //支持比较操作
    auto iter = p1.begin(); //支持迭代器来迭代其中的字符串

3.2 创建、删除、复制文件夹

    boost::filesystem::create_directory(p1); //创建一级目录
    boost::filesystem::create_directories(p1); //创建多级目录
    boost::filesystem::remove(p1); //删除文件或空目录
    boost::filesystem::remove_all(p1); //删除目录
    boost::filesystem::copy_file(p1, p2); //拷贝

3.3 遍历文件夹

// 方法1
void recursive_dir(const boost::filesystem::path& dir)
{
    //使用directory_iterator递归遍历目录
    boost::filesystem::directory_iterator end; //空的directory_iterator构造函数生成一个指向end的迭代器
    boost::filesystem::directory_iterator pos(dir); //传入一个path对象后可以使用++开始迭代操作
    for (; pos != end; pos++)
    {
        if (boost::filesystem::is_directory(*pos))
            recursive_dir(*pos); //directory_iterator迭代器返回的类型其实不是path,但它定义了一个到path的类型转换函数,因此这里是隐式转换
        else
            cout << *pos << endl;  //输出文件名
    }
}
 
// 方法2,支持深度遍历
    boost::filesystem::recursive_directory_iterator end;
    boost::filesystem::recursive_directory_iterator pos(p1);
    for (; pos != end; pos++)
    {
        std::cout << pos.level() << std::endl; //获得当前目录深度
        std::cout << *pos << std::endl; //输出文件名
    }
// 方法2的指针模式
    boost::filesystem::recursive_directory_iterator * end;
    boost::filesystem::recursive_directory_iterator * pos;
    end = new boost::filesystem::recursive_directory_iterator();
    pos = new boost::filesystem::recursive_directory_iterator(p1);
    for (; *pos != *end; (*pos)++)
    {
        std::cout << **pos << std::endl; //输出文件名
    boost::filesystem::path p = **m_pos;
        if (p.extension().string() == ".jpg" ) { // 判断该文件是否是jpg格式的
        }

    }

3.4 判断

    boost::filesystem::exists(p1); //是否存在
    boost::filesystem::is_directory(p1); //是否是目录
    boost::filesystem::is_regular_file(p1); //是否是普通文件
    boost::filesystem::is_empty(p1); //目录是否为空或文件大小是否为0
    boost::filesystem::is_symlink(p1); //是否为链接文件
    boost::filesystem::is_other(p1); //当文件存在且不是普通文件、目录或链接文件时返回true,其它文件类型可以通过文件状态类file_status获得
 
    std::string strDir = p1.string(); //获取字符串(构造函数中传入的字符串为相对路径的话这里也是相对路径)
    bool bRes = boost::filesystem::portable_posix_name(strDir); //判断是否符合posix文件命名规范
    boost::filesystem::windows_name(strDir); //判断是否符合windows文件命名规范
    boost::filesystem::portable_name(strDir); //相当于portable_posix_name() && windows_name
    boost::filesystem::native(strDir); //在windows下相当于windows_name,其它操作系统下只是简单的判断文件名不是空格且不含斜杠
 
    p1.is_complete(); //是否是一个完整的绝对路径
  • 路径
    boost::filesystem::current_path(); //获得当前路径
    boost::filesystem::path parentPath = p3.parent_path(); //获得父路径
    boost::filesystem::path parentPath = p3.system_complete(); //获得全路径(绝对路径)
    boost::filesystem::initial_path(); //获得进入main函数时的当前路径
 
    p1.relative_path(); //获得path的相对路径
    p1.root_path(); //根路径: "C:/"
    p1.root_name(); //根名字:"C:"
    p1.root_directory(); //根目录: "/"

3.5 文件名

    std::string name = p2.filename().string(); //文件名: data.dat
    std::string s = p2.stem().string(); //不含扩展名的文件名: data
    std::string extName = p2.extension().string(); //扩展名: .dat
    boost::filesystem::rename(p1, p2); //改名

3.6 异常处理

    // filesystem使用异常来处理文件操作时发生的错误,所以使用的时候应该加上异常处理
    try
    {
        boost::filesystem::file_size(p1); //获得文件大小,文件不存在则会抛出异常
    }
    catch (boost::filesystem::filesystem_error& e)
    {
        cout << e.path1() << endl;
        cout << e.what() << endl;
    }

3.7 其他

    p1.remove_filename(); //删除当前路径中最后的文件名
    p1.replace_extension("hxx"); //改变文件扩展名
    boost::filesystem::last_write_time(p1); //获得文件最后修改时间
    boost::filesystem::space(p1); //获得路径下磁盘空间分配情况
    boost::filesystem::file_size(p1); //获取文件大小,单位字节
    
 

4 分割字符串

//#include <boost/algorithm/string.hpp>

    std::string line = "sdf  sfd  dfsfd  sdf";
    std::vector<std::string> line_split;
    boost::split(line_split, line, boost::is_any_of("  "), boost::token_compress_on);
    for (std::vector<std::string>::iterator it = line_split.begin();
         it != line_split.end(); it++) {
        std::string a = *it;
        std::cout << a << std::endl;
    }

5 字符串格式化format

将数字和字符串拼接在一起:

//#include <boost/format.hpp>

boost::format fmt("%s/aaa/%06d.png");
std::string s = (fmt % "xxx" % 123).str();
// s == "xxx/aaa/000123.png"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值