读书人

[Boost基础]并发编程Thread多线程

发布时间: 2013-02-02 12:27:16 作者: rapoo

[Boost基础]并发编程——Thread多线程(二)
操作线程

thread类还提供了3个很有用的静态成员函数yield(),sleep(),hardware_concurrency()
yield()函数指示当前线程放弃时间片,允许其他的线程运行;暂停当前正在执行的线程对象,并执行其他线程(注意:这里的其他包括当前线程)
sleep()让线程睡眠等待一小段时间,注意它要求的参数是一个system_time UTC时间点而不是时间长度;使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但他并不释放对象锁,也就是说如果有synchronized同步块,其他线程仍然不能访问共享数据。
hardware_concurrency()可以获得硬件系统可并行的线程数量,即CPU数量或者CPU内核数量,如果无法获取信息则返回0

中断线程
#pragma  once #include <boost/thread.hpp>  #include <boost/bind.hpp>   #include <string>#include <conio.h>   using namespace boost;template <typename T> class basic_atom : boost::noncopyable {private:T n;typedef mutex mutex_t;//互斥量类型定义mutex_t mu;public:basic_atom(T x=T()) : n(x){}//构造函数T operator++()//前置式递增操作符{mutex_t::scoped_lock lock(mu);//锁定互斥量return ++n;}operator T(){return n;}//类型转换操作符定义};mutex muIO;//io流是一个共享资源,不是线程;安全的,需要锁定void printing(basic_atom<int>& x,const std::string& str){for (int i=0;i<5;i++){mutex::scoped_lock lock(muIO);//锁定io流操作std::cout<<str<<++x<<std::endl;}}//e.操作线程//thread类还提供了3个很有用的静态成员函数yield(),sleep(),hardware_concurrency()//yield()函数指示当前线程放弃时间片,允许其他的线程运行;暂停当前正在执行的线程对象,并执行其他线程(注意:这里的其他包括当前线程)//sleep()让线程睡眠等待一小段时间,注意它要求的参数是一个system_time UTC时间点而不是时间长度;使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但他并不释放对象锁,也就是说如果有synchronized同步块,其他线程仍然不能访问共享数据。//hardware_concurrency()可以获得硬件系统可并行的线程数量,即CPU数量或者CPU内核数量,如果无法获取信息则返回0void test4(){        thread t1(std::printf,"printf=%d",5);  std::printf("\n1----%d\n",t1.get_id());//每次都有变化  //成员函数get_id()返回线程的id对象 t1.detach();//使线程对象与函数对象分离 std::printf("\n2----%d\n",t1.get_id());//始终是0//thread::yield();thread::sleep(get_system_time()+posix_time::seconds(2));basic_atom<int> x;//原子操作的计数器//使用临时thead对象启动线程thread(printing,ref(x),"hello8888 ");//向函数传递多个参数std::cout<<"thread::hardware_concurrency "<<thread::hardware_concurrency()<<std::endl;//thread库也在子命名空间this_thread里提供了3个自由函数:get_id(),yield(),sleep()用于操作当前线程。它们的功能同thread类的同名函数相同。分别用于获得线程的id,放弃时间片和睡眠等待。但是this_thread的sleep()函数不仅可以使用绝对的UTC时间点,也可以使用时间长度。this_thread::sleep(posix_time::seconds(2));//睡眠2秒钟std::cout<<this_thread::get_id()<<std::endl;this_thread::yield();}void to_interrupt(basic_atom<int>&x,const std::string& str){try{for (int i=0;i<5;i++){this_thread::sleep(posix_time::seconds(1));//睡眠1秒钟mutex::scoped_lock lock(muIO);//锁定io流操作std::cout<<str<<++x<<std::endl;}}catch (thread_interrupted&){std::cout<<"thread_interrupted"<<std::endl; } }void my_interruption_point(basic_atom<int>&x,const std::string& str){try{for (int i=0;i<5;i++){ mutex::scoped_lock lock(muIO);//锁定io流操作std::cout<<str<<++x<<std::endl;this_thread::interruption_point();//这里允许中断}}catch (thread_interrupted&){std::cout<<"interruption_point"<<std::endl;} }void toto_interrupt(basic_atom<int>&x,const std::string& str){ try{using namespace this_thread;//打开this_thread命名空间assert(interruption_enabled());//此时允许中断for (int i=0;i<5;i++){disable_interruption di;  //关闭中断assert(!interruption_enabled());//此时中断不可用mutex::scoped_lock lock(muIO);//锁定io流操作std::cout<<str<<x++<<std::endl;std::cout<<this_thread::interruption_requested()<<std::endl;this_thread::interruption_point();//中断点被禁用restore_interruption ri(di);//临时恢复中断assert(interruption_enabled());//此时中断可用std::cout<<"can interrupted"<<std::endl;std::cout<<this_thread::interruption_requested()<<std::endl;this_thread::interruption_point();//可并中断}//离开作用域,di/ri都被析构,恢复线程最初的可中断状态assert(interruption_enabled());//此时允许中断}catch (thread_interrupted&){} }//中断线程void test5(){//thread的成员函数interrupt()允许正在执行的线程被中断,被中断的线程会抛出一个thread_interrupted异常,它是一个空类,不是std::exception或者boost::exception的子类。thread_interrupted异常应该在线程执行函数里捕获并处理,如果线程不处理这个异常,那么默认的动作时中止(不结束)线程。basic_atom<int> x;thread t(to_interrupt,ref(x),"hello");this_thread::sleep(posix_time::seconds(2));t.interrupt();t.join();//因为线程已经中断,所有join()立刻返回// 输出 hello1 hello2 thread_interrupted 并没有输出 hello3,4,5//this_thread::sleep(posix_time::seconds(10));}void test6(){//线程的中断点//线程不是在任意时刻都可以被中断的。如果我们将to_interrupt()函数中的sleep()睡眠等待去掉,那么即使在主线程中调用interrupte()线程也不会被中止。//thread库预定义了若干个线程的中断点,只有当线程执行到中断点的时候才能被中断,一个线程可以拥有任意多个中断点。thread库定义了共9个中断点,它们都是函数//1.thread::join()//2.thread::timed_join()//3.condition_variable::wait()//4.condition_variable::timed_wait()//5.condition_variable_any::wait()//6.condition_variable_any::timed_wait();//7.thread::sleep()//8.this_thread::sleep()//9.this_thread::interruption_poin().//这些中断点中的前8个某种形式的等待函数,表明线程在阻塞等待的时候可以被中断。而最后一个位于子名字空间this_thread的interruption_proint()则是一个特别的中断点函数,它并不等待,只是起到一个标签的作用,表示线程执行到这个函数所在的语句就可以被中断。basic_atom<int> y;thread tt(my_interruption_point,ref(y),"helloy");//启动线程tt.interrupt();//然后立即中断线程tt.join();//输出 helloy1 interruption_point}void test7(){//启动/禁用线程中断//缺省情况下线程都是允许中断的,但thread库允许控制线程的中断行为。//thread库在子名字空间this_thread提供了一组函数和类来共同完成线程的中断启用和禁用//interruption_enabled()函数检测当前线程是否允许中断//interruption_requested()函数检测当前线程是否被要求中断//类disable_interruption是一个RAII类型的对象,它在构造是关闭线程的中断,析构是自动ongoing恢复线程的中断状态。在disable_interruption的生命期内线程始终是不可中断的,除非使用了restore_interruption对象//restore_interruption只能在disable_interruption的作用域内使用,它在构造时临时打开线程的中断状态,在析构时又关闭中断状态。basic_atom<int> z;thread ttt(toto_interrupt,ref(z),"helloz");//启动线程ttt.interrupt();//然后立即中断线程ttt.join();//输出  helloz1;1;can interrupted;1;  //允许结构中的两行"1"是函数this_thread::interruption_requested()的输出结构,它表明线程已经收到了中断请求,但因为第一次线程不允许中断,故线程继续执行,直到restore_interruption对象临时恢复了可中断的时候线程在被中断。}void test(char t){std::cout<<"press key====="<<t<<std::endl;switch (t){  case '4':test4();break;case '5':test5();break; case '6':test6();break;case '7':test7();break; case 27:case 'q':exit(0);break;default: std::cout<<"default "<<t<<std::endl;break;}}void main(){while(1) test(getch()); }

读书人网 >操作系统

热点推荐