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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hffhjh111/article/details/53141324

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()启动自己。

类摘要:


  
  
  1. Class Thread
  2. { //不可拷贝
  3. Public:
  4. Thread();
  5. Explicit thread(F f); //传递可调用对象
  6. Thread(F f, A1 a1, A2 a2, ...); //传递可调用对象及参数
  7. Thread(thread&&) noexcept; //转移构造函数(C++11)
  8. Thread& operator = (thread&&) noexcept; //转移赋值函数(C++11)
  9. Bool joinable() const; //是否可join
  10. Void join(); //等待线程
  11. Void detach(); //分离线程
  12. Bool try_join_for(const duration& rel_time); //超时等待(非C++11)
  13. Bool try_join_until(const time_point& t); //超时等待(非C++11)
  14. Void interrupt(); //中断线程(非C++11)
  15. Bool interruption_requested() const; //判断是否被中断(非C++11)
  16. Class id; //内部类线程ID
  17. Id get_id() const; //获得线程id对象
  18. Native_handle_type native_handle(); //获得系统操作相关的handle
  19. Static unsigned hardware_concurrency(); //获得可并发核心数
  20. Static unsigned physical_concurrency(); //获得真实CPU核心数
  21. };
  22. namespace this_thread{
  23. Thread:: id ger_id(); //获得线程ID对象
  24. Void yield(); //允许重复调度线程
  25. Void sleep_nutil(const time_point&t); //睡眠等待
  26. Void sleep_for(const duration& d); //睡眠等待
  27. }


2.Start_Thread

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

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

用法:


  
  
  1. #include<iostream>
  2. #include<boost/thread/thread.hpp>
  3. #include<boost/chrono.hpp>
  4. #include<boost/bind.hpp>
  5. #include <boost/ref.hpp>
  6. using namespace std;
  7. using namespace boost;
  8. void Alloa(string name)
  9. {
  10. cout << "Alloa! " << name << ". __ Asuna" << endl;
  11. /*for (int i = 0; i < 10; i++)
  12. {
  13. cout << i << ' ';
  14. }*/
  15. }
  16. class mycount
  17. {
  18. int id;
  19. public:
  20. mycount( int d = 0) :id(d){}
  21. void operator()()
  22. {
  23. cout << "Alloa ! " << id << endl;
  24. }
  25. void Say(string name)
  26. {
  27. cout << name << endl;
  28. }
  29. };
  30. class ForThread
  31. {
  32. //类内创建线程
  33. public:
  34. static void Hello()
  35. {
  36. this_thread::sleep_for(boost::chrono::milliseconds( 10000));
  37. cout << "ForTHread::HELLO 类内线程" << endl;
  38. }
  39. static void start()
  40. {
  41. thread t(Hello);
  42. t.join();
  43. }
  44. };

  
  
  1. int main()
  2. {
  3. cout << "此线程ID" << this_thread::get_id() << endl;
  4. //this_thread::sleep_for(boost::chrono::microseconds(100));//此线程睡眠100MS
  5. //this_thread::yield();//允许CPU调度让出执行权
  6. thread t1, t2;
  7. cout << t1.get_id() << endl;
  8. assert(t1.get_id() == t2.get_id());
  9. //*******************以下皆为拷贝传递**************************//
  10. ////////////////////// 1 /////////////////////////////////
  11. thread t1(&Alloa,"YWF"); //都可
  12. thread t2(Alloa, "YWF");
  13. t1.detach();
  14. t1.join();
  15. ///////////////////// 2 复杂对象作为参数////////////////////
  16. mycount c(1); //必须重载()
  17. thread thrd1(c); //自动执行c();
  18. thrd1.join();
  19. ///////////////////// 3 类内部创建线程 ///////////////////
  20. ForThread Forthrd; //可以设置成仅有一个实例可以运行的哦!
  21. Forthrd.start(); //主线程会等待函数返回哦!
  22. ///////////////////// 4 类内部函数在类外创建 ////////////////
  23. mycount my(10);
  24. thread th2(boost::bind(&mycount::Say, &my,"ZGJ"));
  25. cout << "th2.joinable = " <<th2.joinable() << endl;
  26. th2.join();
  27. ///*****************引用传参********************************///
  28. string argv1 = "YWFAHX";
  29. thread th2(boost::bind(Alloa, boost::ref(argv1)));
  30. //this_thread::sleep_for(boost::chrono::milliseconds(1000));//此线程睡眠100MS
  31. cout << "END OF MAIN" << endl;
  32. return 0;
  33. }

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:


  
  
  1. #include<iostream>
  2. #include<boost/thread/thread.hpp>
  3. #include<boost/chrono.hpp>
  4. #include<boost/bind.hpp>
  5. using namespace std;
  6. using namespace boost;
  7. void Alloa(string name)
  8. {
  9. try
  10. {
  11. using namespace this_thread;
  12. assert(interruption_enabled()); //测试是否允许中断
  13. {
  14. disable_interruption dis;
  15. assert(!interruption_enabled()); //此时不允许中断
  16. cout << "Alloa! " << name << ". __ Asuna" << endl;
  17. this_thread::sleep_for(chrono::milliseconds( 2));
  18. interruption_point();
  19. //restore_interruption ri(dis);//下面的中断是否可用
  20. assert(interruption_enabled()); //可用
  21. cout << interruption_enabled() << endl;
  22. interruption_point();
  23. }
  24. assert(interruption_enabled());
  25. cout << "END Alloa" << endl;
  26. interruption_point();
  27. }
  28. catch ( const thread_interrupted)
  29. {
  30. cout << "thread_interrupted" << endl;
  31. }
  32. }
  33. int main()
  34. {
  35. thread t1(Alloa, "YWF");
  36. //this_thread::sleep_for(chrono::milliseconds(1));
  37. t1.interrupt();
  38. assert(t1.interruption_requested());
  39. t1.join();
  40. return 0;
  41. }





版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hffhjh111/article/details/53141324

猜你喜欢

转载自blog.csdn.net/monk1992/article/details/82868519