BOOST之Thread库学习

//Boost并发编程之thread

/*-----------------------------------------------------编译thread库

在工程中嵌入源码的方式:

直接在cpp文件中包含thread库的实现代码如下

#define BOOST_DATE_TIME_SOURCE

#define BOOST_THREAD_NO_LIB

#inclue<boost\thread.hpp>

#ifdef _MSC_VER              //windows线程

extern "C" void tss_cleanup_implemented(void)()//一个必须的函数window下的thread库没有实现自动tss功能

#include<libs\thread\src\win32\thread.cpp>

#incldue<libs\thread\src\win32\tss_dll.cpp>

#include<libs\thread\src\win32\tss_pe_cpp>

#else

#include<lib\thread\src\pthread\thread.cpp>

#include<libs\thread\src\pthread\once.cpp>

#endif

-------------------------------------------------使用thread库

#define BOOST_DATE_TIME_SOURCE

#define BOOST_THREAD_NO_LIB

#include <boost\threaad.hpp>

--------------------------------------------时间功能

为了更好的表述时间线程的相关含义thread库重新定义新的时间类型system_time 他是posix::ptime同义词

thread库也提供一个自由函数get_system_time()它调用microse_clock类方便地获取当前utc时间

-------------------------------------------互斥量

Thread提供7中互斥量类型(实际上只有5中)

(1) Mutex:独占式的互斥量,最简单的一种互斥量类型

(2) Try_mutex:mutex同义为兼容以前版本

(3) Time_mutex:独占式,提供超时锁定功能

(4) Recursive_mutex:递归互斥量可以多次锁定

(5) Recursive_try_mutex:它是(4)的同义词为兼容

(6) Recursive_timed_mutex:他是递归式互斥量基本功能同(4)但提供超时锁定

(7) Share_mutex:multiple-reader/single-writer型的共享互斥锁(又称读写锁)

---------------------------------------互斥量的用法

直接使用mutex的成员函数来锁定互斥量不够方便而且在发生异常导致退出作用的情况下很可能忘记解除所覅那个;因此thread库提供一系列RAII型的lock_guard类由于辅助锁定互斥量。他们在构造时锁定互斥量在析构时自动解锁从而保证避免忘记解锁,就想一个智能指针

Mutex类使用内部类型定义的scoped_lock和scope_try_lock定义两种guard对象分别对应执行lock()和try_lock()

不适用guard对象:

Mutex mu;

Try{

Mu.lock()

Cout<<”some operation”<<endl;

Mu.unlock

}

Catch(….)

{

Mu.unlock();

}

使用lock_guard 类可以取消麻烦的try_catch块可以改为:

Mutex mu;

Mutex::scoped_lock lock(mu);

Cout<<”some operator”<<endl;

-----------------------------------------------------线程对象

thread类是thread库的核心对象

thread对象时不可拷贝的

thread通过特别的机制支持转移语义因此我们可以创建线程工程函数来封装threa创建细节返回一个thread对象

template<typename F>

thread_make(F f)

{

return thread(f);

}

---------------------------------------------------创建线程

thread 支持最多9个参数的传递且支持直接传递参数

---------------------------------------------------启动线程

当创建一个thread对象后线程立刻开始执行不提供类似start和begin那样用法

mutex io_mu

void printing(atom_int& x,const string& str)

{

for(int i=0;i<5;i++)

{

mutex::scoped_lock lock(io_mu)

cout<<str<<++x<<endl;

}

}

int main()

{

atom_int x;

thread(printing,ref(x),"hello");//传递多个参数

this_thread::sleep(posix_time::seconds(2));//等待2秒

}

----------------------------------------join和time_join

joinable()可以判断thread对象是否标示一个可执行的线程体如果joinable()返回true我们就可以调用join或者time_join来等待执行线程的结束

join()一直等待,time_join()等一时间段

----------------------------------------与线程执行体的分离

使用detach将thread与执行体手动分离此后thread对象不代表任何线程体,失去对线程的控制

thread t1(printing,ref(x),"hello");

t1.detach();

----------------------------------------bind和function的使用

bind库可以把函数所需的参数bind到一个函数对象上,而function则可以存储bind表达式的结果,供以后使用

thread t3(bind(printing),ref(x),"thread");

function<void()>f=bind(printing,5,"mutex");

thread(f);

----------------------------------------操作线程

get_id可以返回线程的id对象线程id提供了完整的比较操作符合流输出操作因此可以用标准容器管理

thread提供了三个静态成员函数

yield()  当前线程放弃时间片

sleep()让线程睡眠等待一段时间

hardware_concurrency()获取cpu数量或者cpu内核数量

-----------------------------------------中断线程

thread的成员函90数interrupt()允许正在执行的线程被中断被中断的线程会抛出thread_interrupted异常他是空类应该在线程执行函数里铺货并处理如果不处理那么就是终止线程

---------------------------------------线程中断点

thread 库预定义了若干个线程中断点,只有当线程执行到中断点的时候才能被中断,一个线程可以有任意多个中断点

预定义的9个中断点

thread::join();

thread::timed_join();

condition_variable::wait();

condition_variable::timed_wait();

condition/-cariable_any::wait();

condition/-cariable_any::timed_wait()

thread::sleep()

this_tread_sleep()

this_thread::interruption_point()

--------------------------------------------启用和禁用线程中断

interruption_enable()函数检测当前线程是否允许中断

interruption_requested()函数检测当前线程是否被要求中断

类disable_interruption 是RAII类型对象构造时关闭线程中断,析构时自动恢复中断,再其生命周期内始终是不可中断的除非使用了restore_interruption对象

restore_interruption对象只能在disable_interruption生命期内使用它在构造时临时打开线程中断状态析构时关闭中断状态

-------------------------------------------线程组

thread库提供类thread_group用于管理一组线程就像是线程池内部使用std::list<thread*>来容纳创建thread对象

create_thread()是一个工厂函数,可以创建thread对象并运行线程同时加入到内部的list中。

add_thread()提供加入线程组中

还有类似提供:

remove_thread()和join_all()interrupt_all()函数

thread_group tg;

tg.create_thread(bind(printing,ref(x),"C++"));

tg.create_thread(bind(printing,ref(x),"boost"));

------------------------------------------------------条件变量

thread库提供两种条件变量对象 condition_variable和condition_variable_any 一般情况下使用后一种

拥有条件变量的线程先锁定互斥量然后循环检查某个条件如果条件不满足那就调用条件变量的成员函数wait()等待直至条件满足,其他线程处理条件

变量要求的条件,当条件满足时调用它的成员函数notify_one()或notify_all(),通知所有正在等待条件的变量线程停止等待继续执行

------------------------------------------------用法

可以使用标准库的容器适配器queue介绍circular_buffer类来实现先进先出型和循环队列型缓冲区

class DataBuffer

#endif

{

public:

DataBuffer(size_t n) :unread(0), capacity(n){}

void put(const T& x);

void get(const T&x);

private:

mutex mu;

condition_variable_any cond_put;

condition_variable_any cond_get;

queue<T>stk;

int unread;

int capacity;

bool is_full()

{

return unread == capacity;

}

bool is_empty()

{

return unread == 0;

}

};

template<typename T>

DataBuffer<T>::DataBuffer()//初始情况下rnread=0;capacity=10;

{

unread = 0;

capacity = 10;

}

template<typename T>

void DataBuffer<T>::put(const T&x)

{

{

mutex::scoped_lock lock(mu);

while (is_empty())

{

{

/*缓冲区为空则等待*/

}

cond_get.wait(mu);

}

--unread;

*x = stk.front();

stk.pop();

}

cond_put.notify_one();

}

template<typename T>

void DataBuffer<T>::get(const T& x)

{

{

mutex::scoped_lock lock(mu);

while (is_full())

{

{

/*缓冲区满*/

}

cond_put.wait(mu);

}

stk.push(x);

++unread;

}

cond_get.notify_one();

}

template<typename T>

DataBuffer<T>::~DataBuffer()

{

}

-------------------------------------------------------------共享互斥变量

共享互斥量shared_mutex不同于mutex和recursive_mutex,它允许线程获取多个共享所有权和一个专享所有权实现了读写锁机制

如果要获取共享权的使用需调用lock_shared()或者try_lock_shared(),相应的使用unlock_shared来释放所有权

shared_mutex么有提供内部的lock_guard类型定义因此必须直接使用lock_guard对象

读锁定时使用shared_lock<shared_mutex>,写锁定时使用unique_lock<shared_mutex>

--------------------------------------------------使用

------------------------------------------future

thread库使用future范式提供一种异步操作线程返回值的方法因为这个返回值在线程开始执行时还是不可用的

packaged_task和promise两个模板类来包装异步调用,用unique_future和shared_future来获取异步调用结果

------------------packaged_task好像是一个reference_wrapper 或者function对象,它提供opertor()包装一个可回调物然后就可以被任意线程调用最后future值可以用成员函数get_future()获得

unique_future 用来存储packaged_task异步计算的future值,他只能持有唯一的一个引用

----------------------使用方法:

int fab(int n)//递归计算斐波那契数列

{

}

*/

#include<boost\thread.hpp>

#include<iostream>

using namespace std;

using namespace boost;

int fab(int n)//递归计算斐波那契数列

{

if (n == 0 || n == 1)

{

return 1;

}

return fab(n - 1) + fab(n - 2);

}

int main()

{

packaged_task<int>pt(bind(fab,30));//声明packaged_task对象用模板参数指明返回值的类型packaged_task只接受无参函数因此需要bind

unique_future<int> uf = pt.get_future();//声明unqiue_future对象接受packaged_task的future值 同样使用模板参数指明返回类型

thread(boost::move(pt));//启动线程计算必须使用boost::move()来转移pack_task对象因为packaged_task是不可拷贝的

uf.wait();//uf等待计算结果

assert(uf.is_ready() && uf.has_value());

cout << uf.get() << endl;

}

时间: 2024-08-24 11:16:29

BOOST之Thread库学习的相关文章

初探boost之timer库学习笔记

timer 用法 #include <boost/timer.hpp> #include <iostream> using namespace std; using namespace boost; int main() { timer t;//声明一个计时器对象,开始计时 cout<<"max:"<<t.elapsed_max()/3600<<"h"<<endl; //可度量的最大时间,以小时

初探boost之progress_display库学习笔记

progress_display 用途 progress_display可以在控制台上显示程序的执行进度,如果程序执行很耗费时间,那么它能提供一个友好的用户界 面,不至于让用户在等待中失去耐心,甚至怀疑程序的运行是否出了问题. 用法示例 #include <boost/progress.hpp> #include <iostream> #include <vector> using namespace std; using namespace boost; int ma

初探boost之smart_ptr库学习笔记

概述 Boost.smart_ptr库提供了六种智能指针,除了shared_ptr 和 weak_ptr 以外还包括 scoped_ptr .scoped_array . shared_array .intrusive_ptr .他们的速度与原始指针相差无几,都是异常安全的,而且对于类型T也仅有一个要 求:类型T的析构函数不能抛出异常. 使用时包含头文件: #include<boost/smart_ptr.hpp> scoped_ptr 用法: scoped_ptr 的构造函数接受一个类型为T

初探boost之pool库学习笔记

pool 内存池概述 通常我们习惯直接使用new.malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能. 内存池则是在真正使用内存之前,先申请分配一定数量的.大小相等(一般情况下)的内存块留作备用.当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存.这样做的一个显著优点是尽量避免了内存碎片,使得内存分配效率得到提升. pool库概述 pool库实现了一个快速.紧凑的内存池库,不仅能够管理大量的

【python标准库学习】thread,threading(二)多线程同步

继上一篇介绍了python的多线程和基本用法.也说到了python中多线程中的同步锁,这篇就来看看python中的多线程同步问题. 有时候很多个线程同时对一个资源进行修改,这个时候就容易发生错误,看看这个最简单的程序: import thread, time count = 0 def addCount(): global count for i in range(100000): count += 1 for i in range(10): thread.start_new_thread(ad

【python标准库学习】thread,threading(一)多线程的介绍和使用

在单个程序中我们经常用多线程来处理不同的工作,尤其是有的工作需要等,那么我们会新建一个线程去等然后执行某些操作,当做完事后线程退出被回收.当一个程序运行时,就会有一个进程被系统所创建,同时也会有一个线程运行,这个线程就是主线程main,在主线程中所创建的新的线程都是子线程,子线程通常都是做一些辅助的事.python中提供了thread和threading两个模块来支持多线程. python中使用线程有两种方式,第一种是用thread模块的start_new_thread函数,另一种是用threa

c++ boost库学习三:实用工具

noncopyable 大家都知道定义一个空类的时候,它实际包含了构造函数,拷贝构造函数,赋值操作符和析构函数等. 这样就很容易产生一个问题,就是当用户调用A a(“^_^") 或者A c="^_^" 时会发生一些意想不到的行为,所以很多时候我们需要禁用这样的用法. 一种方法就是把拷贝构造函数和赋值操作符显式的定义为private,但是这样需要很多代码. 于是boost库为大家提供了一个简单的方法:只需要将类继承于noncopyable就可以了. #include "

Boost::thread库的使用

阅读对象 本文假设读者有几下Skills [1]在C++中至少使用过一种多线程开发库,有Mutex和Lock的概念. [2]熟悉C++开发,在开发工具中,能够编译.设置boost::thread库. 环境 [1]Visual Studio 2005/2008 with SP1 [2]boost1.39/1.40 概要 通过实例介绍boost thread的使用方式,本文主要由线程启动.Interruption机制.线程同步.等待线程退出.Thread Group几个部份组成. 正文 线程启动 线

boost库学习之regex

一.背景 项目中许多地方需要对字符串进行匹配,比如根据指定的过滤字符串来过滤文件名.刚开始是排斥使用boost库的,第一,我不熟悉boost库:第二,如果引入第三方库,就会增加库的依赖,这样的后果是,要么打包程序时,打包动态库,要么直接使用静态库编译,会使增大程序的大小. 刚开始是尝试自己写模糊匹配算法,很简单,就只支持_和%,这两个通配符,然后发现Linux下有一个fnmatch的函数,就是进行模糊匹配的,它支持shell通配符. 但是到最后发现,当需要区别很相似的字符串时,模糊匹配就不行了,