4.2.2.6 其它类属
Thread 线程类 这个类中的一些静态函数用于线程的创建等.
它是一个原始的东西. 通常应该使用Thread_Manager类而不是它.
atomic_Ops 封装了对于内置数据类型(如int)的算术操作(如++). 使这种操作成为线程安全的(原子的).
//例子代码
template <class TYPE>
class Atomic_Op {
public:
Atomic_Op (void) { count_ = 0; }
Atomic_Op (TYPE c) { count_ = c; }
TYPE operator++ (void) { //封装了内置类型的算术运算. 使它成为线程安全的.(还有其它的类似++的运算符)
Guard monitor (lock_);
return ++count_;
}
operator TYPE () { //取内部数据类型的值. 返回的是该数据当前值的拷贝.
Guard monitor_ (lock_);
return count_;
}
// Other arithmetic operations omitted...
private:
Thread_Mutex lock_;
TYPE count_;
};
4.5.4 ACE线程管理器类
4.5.4.1 Thread_Manager类. //这节的笔记来自<<中篇: ACE程序员教程>> 4.3节
它用来管理成组的线程 和 任务(ACE_Task).
它比ACE_Thread类的功能更多. 它不仅可以创建/销毁一组线程. 还可以对它们挂起和恢复.
也可以发送信号给某一组线程. 或者是在一组线程上等待.
这个类使用了单件模式. 用 ACE_Thread_Manager* Thr_Manager = ACE_Thread_Manager::instance() 来取得该对象.
/////////////////////////////////////////////////////////////////////
// 使用Thread_Manager来管理线程的例子. (来自<<ACE程序员教程>>49页)
/////////////////////////////////////////////////////////////////////
// 演示怎么使用ACE_Thread_Manager类来对线程组进行 挂起/恢复
// 以及协作式撤销(就是对线程设置一个状态.让该线程的代码检测该状态后退出).
#include "ace/Thread_Manager.h"
static const int DEFAULT_THREADS = ACE_DEFAULT_THREADS;
static const int DEFAULT_ITERATIONS = 100000;
static void * worker (int iterations) {
for (int i = 0; i < iterations; i++) {
if ((i % 1000) == 0) { //每循环1000次检测一下"当前线程是否正请求撤销".
ACE_DEBUG ((LM_DEBUG, "(%t) checking cancellation before iteration %d!/n", i));
//用单件ACE_Thread_Manager对象的testcancel()来测试是否撤销一个线程.
// 所以看上去ACE_Thread::self()可以取得当前正在执行的线程(ACE_thread_t).
if (ACE_Thread_Manager::instance ()->testcancel (ACE_Thread::self ()) != 0) {
ACE_DEBUG ((LM_DEBUG, "(%t) has been canceled before iteration %d!/n",i));
break;
}
}
}
return 0;
}
int main (int argc, char *argv[])
{
int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_THREADS; //线程数
int n_iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_ITERATIONS; //线程函数中的循环的次数.
ACE_Thread_Manager *thr_mgr = ACE_Thread_Manager::instance (); //取得单件的线程管理器对象
// 下边的 ACE_Thread_Manager::spawn_n()创建的是一组线程们.
// 在本例子中是创建一组共n_threads个线程.
// 这一组线程都执行第2个参数指定的线程函数.
// 第3个参数指定将要传递给线程函数的参数. 第4个是一些旗标. 默认THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED.
// 还有其它一些参数. 指定线程堆栈. 优先级等. 这个函数除了前两个参数外都有默认值.
// 它返回创建的这个线程组的组ID.
int grp_id = thr_mgr->spawn_n (
n_threads, //这个线程组的线程数
ACE_THR_FUNC (worker), //这组线程的线程函数
(void *) n_iterations, // 传递给线程函数的参数.
THR_NEW_LWP | THR_DETACHED); //旗标.
ACE_OS::sleep (1); //主线程休息1秒.
ACE_DEBUG ((LM_DEBUG, "(%t) suspending group/n"));
if (thr_mgr->suspend_grp (grp_id) == -1) //让一组线程挂起
ACE_ERROR ((LM_DEBUG, "(%t) %p/n", "Could not suspend_grp"));
ACE_OS::sleep (1);
ACE_DEBUG ((LM_DEBUG, "(%t) resuming group/n"));
if (thr_mgr->resume_grp (grp_id) == -1) // 让一组线程唤醒
ACE_ERROR ((LM_DEBUG, "(%t) %p/n", "resume_grp"));
// Wait for 1 more second and then cancel all the threads.
ACE_OS::sleep (ACE_Time_Value (1));
ACE_DEBUG ((LM_DEBUG, "(%t) canceling group/n"));
if (thr_mgr->cancel_grp (grp_id) == -1) // 请求一组线程撤销. 所以线程函数中要有配合的代码. 如worker()所示.
ACE_ERROR ((LM_DEBUG, "(%t) %p/n", "cancel_grp"));
// 等待线程管理器中所有的线程结束.
thr_mgr->wait ();
return 0;
}
4.5.6 其它类
TSS(线程专有存储)
ACE中使用模板类ACE_TSS来解决"线程专有存储"的问题. 它的使用很简单:
需要成为线程专有的类被传入ACE_TSS 模板. 然后可以使用C++的->操作符来调用它的全部公共方法.
(原理是不是在该类的 operator-> 函数中先取得当前线程的句柄. 再根据线程句柄映射到该线程专有的对象上)
///////////////////////////////////////////////////////////
// 使用ACE_TSS的一个例子. 来自<<ace程序员教程>>4.4节 51页
///////////////////////////////////////////////////////////
#include "ace/Synch.h"
#include "ace/Thread_Manager.h"
class DataType {
public:
DataType():data(0){}
void increment(){ data++;}
void set(int new_data){ data=new_data;}
void decrement(){ data--;}
int get(){return data;}
private:
int data;
};
// 构造全局的线程专有对象. 是不是很简单?
ACE_TSS<DataType> data;
// 测试线程1. 其中使用全局的 data. 但实际上它们使用的是各自的线程专有的.
static void* thread1(void*) {
data->set(10);
ACE_DEBUG((LM_DEBUG,"(%t)The value of data is %d /n",data->get()));
for(int i=0;i<5;i++)
data->increment();
ACE_DEBUG((LM_DEBUG,"(%t)The value of data is %d /n",data->get()));
return 0;
}
// 测试线程2. 其中使用全局的data. 但实际上它们使用的是各自的线程专有的.
static void * thread2(void*) {
data->set(100);
ACE_DEBUG((LM_DEBUG,"(%t)The value of data is %d /n",data->get()));
for(int i=0; i<5;i++)
data->increment();
ACE_DEBUG((LM_DEBUG,"(%t)The value of data is %d /n",data->get()));
return 0;
}
int main(int argc, char*argv[]) {
// 注意这里的ACE_Thread_Manager::spawn()函数. 它和spawn_n()很相似. 但它只创建一个线程.
ACE_Thread_Manager::instance()->spawn((ACE_THR_FUNC)thread1,0,THR_NEW_LWP|THR_DETACHED);
ACE_Thread_Manager::instance()->spawn((ACE_THR_FUNC)thread2,0,THR_NEW_LWP| THR_DETACHED);
// 等待线程管理器中所有的线程结束.
ACE_Thread_Manager::instance()->wait();
ACE_DEBUG((LM_DEBUG,"Both threads done.Exiting.. /n"));
}