您的位置:首页 > 其它

libjingle开发系列之二:线程管理

2010-12-14 13:38 120 查看
先从ThreadManager类说起:

这是一个全局的线程管理类,在thread.cc中定义。
这个类的核心功能在于提供线程对象注册的功能。提供了一个很方便的函数CurrentThread,如下面的场景:
// Check that we're being called from the channel (e.g., worker) thread.
ASSERT(talk_base::ThreadManager::CurrentThread() == channel_thread_);
channel_thread_->Clear(this);
注意,CurrentThread是在当前线程已经有Thread类关联的情况下,会返回该类,否则单纯返回NULL。
如果要自动生成新的Thread类,请使用WrapCurrentThread,详细看注释。

下面对该类的实现做详细的解析:

通常实现线程类,是通过在CreateThread中将对象指针最为线程函数的参数的方法来实现的。
libjingle库则采用了Tls来实现,即将对象指针放入TLS分配的内存中。首先看TreadManager的初期化:
(方便期间用的是windows的代码,linux的实现机制是一样的)
ThreadManager g_thmgr;
DWORD ThreadManager::key_;
ThreadManager::ThreadManager() {
key_ = TlsAlloc();
main_thread_ = WrapCurrentThread();
}
作为全局变量的g_thmgr,在程序主线程中被初期化,并且主线程被“wrap”成了第一个Thread类对象,加入Manager的管理。

再来看WrapCurrentThread的实现:
...
Thread* result = CurrentThread();
if (NULL == result) {
result = new Thread();
...
SetCurrent(result);
}
reuturn result;
CurrentThread的实现:
return static_cast<Thread *>(TlsGetValue(key_));
SetCurrent的实现:
TlsSetValue(key_, thread);
熟悉TLS的机制的话应该明白,TlsAlloc返回的key(其实就是数组索引),在第一次被调用的时候返回NULL, 然后就会引发new Thread的, 并将这个指针放入key所指定的内存中。

接着到thread类了:

这个线程实现了OS无关的编程接口,实现模型基本类似java。你可以在Start中提供runnable,

bool Start(Runnable* runnable = NULL);

或是继承thread类,重写虚函数Run,这里Run简单的就是执行消息循环。

virtual void Run();

然后就是libjingle的比较特别的地方了,每一个thread都继承自类MessageQueue。

所谓消息队列,写过windows程序应该都很明白,无非就是一个队列,消息机制的分析以后再写。

关于AutoThread:

就是自动调用SetCurrent把AutoThread和当前线程关联起来。

总结下:

程序任何地方都可以通过Thread::Current() 或是ThreadManager::GetCurrent()获取当前线程的包装类,

同样通过这个包装类可以控制关联线程运行状态,和运行内容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: