C++多线程-第三篇-Thread(线程)

来源:互联网 发布:linux uname -a 编辑:程序博客网 时间:2024/06/06 16:47

Thread

//Boost

#include<boost/thread/thread.hpp>

#define BOOST_THREAD_VERSION 4 //使用最新版本,含有1,2,3但只是为了兼容之前程序。

Thread库丰富强大的扩展功能但不在Thread中的未看。

//C++11

#include<thread>


1.Thread_Class简析

特点:

1.线程对象需要一个可调用物,而调用函数的对象默认是拷贝传参,因此要求可调用物和参数类型都支持拷贝构造。所以如果希望传递给线程引用值就要使用ref库进行包装,同时必须保证被引用对象在线程执行期间一直存在,否则会引发为定义行为。

 

2.线程对象在析构时会调用std::terminate 结束线程的执行,并不会关心线程是否执行完毕,所以要保证函数正确运行完毕必须调用join()等待线程执行函数或者调用detach()分离线程体。

3.Thread实例的析构会导致其表示线程强制终止?

可是测试证实不会!他是在线程中插入结束点等待它自动结束?若线程死锁或者啥的则不会结束,资源也不会释放。

 

4.Thread对象创建完毕就会执行,不提供Start(),但事实上它含有私有成员函数Start_thread()启动自己。

 

类摘要:

Class Thread{//不可拷贝Public:Thread();Explicit thread(F f);//传递可调用对象Thread(F f, A1 a1, A2 a2, ...);  //传递可调用对象及参数 Thread(thread&&) noexcept;//转移构造函数(C++11)Thread& operator = (thread&&)noexcept;//转移赋值函数(C++11)Bool joinable() const;//是否可joinVoid join();//等待线程Void detach();//分离线程Bool try_join_for(const duration& rel_time); //超时等待(非C++11)Bool try_join_until(const time_point& t);//超时等待(非C++11)Void interrupt();//中断线程(非C++11)Bool interruption_requested() const;//判断是否被中断(非C++11)Class id;//内部类线程IDId get_id() const;//获得线程id对象Native_handle_type native_handle();//获得系统操作相关的handleStatic unsigned hardware_concurrency();//获得可并发核心数Static unsigned physical_concurrency();//获得真实CPU核心数};namespace this_thread{Thread::id ger_id();//获得线程ID对象Void yield();//允许重复调度线程Void sleep_nutil(const time_point&t);//睡眠等待Void sleep_for(const duration& d);//睡眠等待}


2.Start_Thread

explicit thread(const boost::function0<void>& threadfunc): 

boost::function0<void>可以简单看为:一个无返回(返回void),无参数的函数。这里的函数也可以是类重载operator()构成的函数;该构造函数传入的是函数对象而并非是函数指针,这样一个具有一般函数特性的类也能作为参数传入

 

用法:

#include<iostream>#include<boost/thread/thread.hpp>#include<boost/chrono.hpp>#include<boost/bind.hpp>#include <boost/ref.hpp>using namespace std;using namespace boost;void Alloa(string name){cout << "Alloa! " << name << ". __ Asuna" << endl;/*for (int i = 0; i < 10; i++){cout << i << ' ';}*/}class mycount{int id;public:mycount(int d = 0) :id(d){}void operator()(){cout << "Alloa ! " << id << endl;}void Say(string name){cout << name << endl;}};class ForThread{//类内创建线程public:static void Hello(){this_thread::sleep_for(boost::chrono::milliseconds(10000));cout << "ForTHread::HELLO  类内线程" << endl;}static void start(){thread t(Hello);t.join();}};
int main(){cout << "此线程ID" << this_thread::get_id() << endl;//this_thread::sleep_for(boost::chrono::microseconds(100));//此线程睡眠100MS//this_thread::yield();//允许CPU调度让出执行权thread t1, t2;cout << t1.get_id() << endl;assert(t1.get_id() == t2.get_id());//*******************以下皆为拷贝传递**************************//////////////////////// 1 /////////////////////////////////thread t1(&Alloa,"YWF");//都可thread t2(Alloa, "YWF");t1.detach();t1.join();///////////////////// 2 复杂对象作为参数////////////////////mycount c(1); //必须重载()thread thrd1(c);//自动执行c();thrd1.join();///////////////////// 3 类内部创建线程 ///////////////////ForThread Forthrd;//可以设置成仅有一个实例可以运行的哦!Forthrd.start();//主线程会等待函数返回哦!///////////////////// 4 类内部函数在类外创建 ////////////////mycount my(10);thread th2(boost::bind(&mycount::Say, &my,"ZGJ"));cout <<"th2.joinable = " <<th2.joinable() << endl;th2.join();///*****************引用传参********************************///string argv1 = "YWFAHX";thread th2(boost::bind(Alloa, boost::ref(argv1)));//this_thread::sleep_for(boost::chrono::milliseconds(1000));//此线程睡眠100MScout << "END OF MAIN" << endl;return 0;}

3.等待线程结束

Join等待线程

Thread的成员函数joinable可以判断thread对象是否标示了一个可执行的线程。

joinable返回true,则可调用

一直阻塞等待直到线程结束

Join();  


阻塞等待一定的时间,然后返回,或者等待的线程完毕返回。

Try_join_for();

Try_join_until();


Detach分离线程 -- 将线程托管给系统,不受控制了!

Detachthread对象与线程执行体手动分离,从此后thread对象不代表任何线程体

Joinable() == false ,从而失去对线程体的控制。

分离后的线程体将不受影响的继续执行,直到函数结束或者随着主线程一起结束。

所以不需要在操作线程体时可利用临时对象启动线程后即可分离。

Thread对象在析构时若其函数仍未执行完毕则自动detach

 

Thread_guard()控制thread对象的析构时行为 类似的有scoped_thread()

Thread_guard()是与Lock_guard()类似的辅助类

#include<boost/thread/thread_guard.hpp>


4.中断/结束线程

中断依靠Interrupted()

通过interrupted_requested()检查是否被要求中断.

被中断的线程会抛出一个thread_interrupted异常(一个空类),应该捕获处理,否则默认动作是终止线程。

线程不是想中断就可以中断,需要等待中断点(手动设置)才可以触发。

Boost::Thread12个中断点(函数)

1. Thread::Join()

2. thread::Try_join_for()

3. thread::try_join_until()

4. Condition_variable::Wait()

5. Condition_variable::wait_for()

6. Condition_variable::wait_until()

7. Condition_variable_any::wait()

8. Condition_variable_any::wait_for()

9. Condition_variable_any::wait_until()

10. This_thread::sleep_for()

11. This_thread::sleep_until()

12. This_thread::interruption_point()//不会等待,只起标签作用,到此处可被中断。

 

启用/禁用中断(选,我没仔细看)

默认线程是可被中断的

但是boost::this_thread里提供了一组函数与类来共同完成现成的中断启/禁用

Interruption_enabled() //检测当前线程是否可中断

Interrupted_requested() //检测当前线程是否被要求中断

disable_interruption 是一个RAII类型的对象,在构造时关闭线程的中断,析构时自动回复线程的中断状态。在disable_interruption生命周期内线程不可中断,除非使用restore_interruption对象

Restore_interruption只可在disable_interruption的作用域内使用,它在构造时临时打开线程的中断状态,析构时又关闭中断状态。


Code:

#include<iostream>#include<boost/thread/thread.hpp>#include<boost/chrono.hpp>#include<boost/bind.hpp>using namespace std;using namespace boost;void Alloa(string name){try{using namespace this_thread;assert(interruption_enabled());//测试是否允许中断{disable_interruption dis;assert(!interruption_enabled());//此时不允许中断cout << "Alloa! " << name << ". __ Asuna" << endl;this_thread::sleep_for(chrono::milliseconds(2));interruption_point();//restore_interruption ri(dis);//下面的中断是否可用assert(interruption_enabled());//可用cout << interruption_enabled() << endl;interruption_point();}assert(interruption_enabled());cout << "END Alloa" << endl;interruption_point();}catch (const thread_interrupted){cout << "thread_interrupted" << endl;}}int main(){thread t1(Alloa, "YWF");//this_thread::sleep_for(chrono::milliseconds(1));t1.interrupt();assert(t1.interruption_requested());t1.join();return 0;}





1 0
原创粉丝点击