有了Vim在手,看代码也成了一种乐趣,今天Maxiee继续分析aMule的代码,今天的主题是线程。这对于只会编简单程序的Maxiee来说还是个新东西。想想aMule同时间内,既要连接ED2K网络,还要连接KAD网络,同时下载那么多文件,这么多任务就要用到多线程。可是Maixee好像记得,线程开不了太多不是?aMule是怎么弄的呢?
为了能理解aMule的wxWidget调用,Maixee还去wxWidget官网上下了个手册,chm格式的30M!
Maxiee的第一反应就是,去看看跟线程(thread)有关的头文件!有了winmanager (Maxiee的Vim入门日记(3)——安装winmanager),我们可以很方便地在Vim里查找,Maxiee找到了这些:
有MuleThread.h、ThreadScheduler.h和ThreadTask.h这三个,Maxiee今天先来研究这个MuleThread.h
在MuleThread.h里,定义了CMuleThread类,它基于wxThread,它的构造很简单,有一个停止(毁灭)方法,有一个测试是否毁灭的方法,这个类很基本,看来有许多操作类都要继承它才行啊。
既然我们装了Cscope( Maxiee的Vim入门日记(4)——安装windows下的Cscope),我们可以来看看CMuleThread都派生出来了哪些类:
有点出乎Maixee的预料,没有想象中的多啊,只有18项,我们把它梳理梳理:
HTTPDoaload、MuleThread、Timer、ThreadScheduler有这么几个关键词其中MuleThread就指我们上面看到的CMuleThread类
我们先看HTTPDoaload.h看看它是怎么继承CMuleThread类的:
我们看到类的定义:
class CHTTPDownloadThread : public CMuleThread
它只有两个公有方法:
CHTTPDownloadThread(const wxString& url, const wxString& filename, const wxString& oldfilename, HTTP_Download_File file_id,
bool showDialog, bool checkDownloadNewer);
static void StopAll();
这跟线程函数有什么关系呢?我们去构造函数里看看:
这是构造函数初始化的一部分:
CHTTPDownloadThread::CHTTPDownloadThread(const wxString& url, const wxString& filename, const wxString& oldfilename, HTTP_Download_File file_id, bool showDialog, bool checkDownloadNewer) #ifdef AMULE_DAEMON : CMuleThread(wxTHREAD_DETACHED), #else : CMuleThread(showDialog ? wxTHREAD_JOINABLE : wxTHREAD_DETACHED), #endif m_url(url), m_tempfile(filename), m_result(-1), m_file_id(file_id), m_companion(NULL)
wxTHREAD_DETACHED和wxTHREAD_JOINABLE分别是什么意思呢?我们去手册里看看:“There are two types of threads in wxWidgets: detached andjoinable, modeled after the POSIX thread API. This is different from the Win32 API where all threads are joinable.”“By default wxThreads in wxWidgets use the detached behaviour. Detached threads delete themselves once they have completed, either by themselves when they complete processing or through a call toDelete(), and thus must be created on the heap (through the new operator, for example).”“Conversely, joinable threads do not delete themselves when they are done processing and as such are safe to create on the stack. Joinable threads also provide the ability for one to get value it returned fromEntry() through Wait(). You shouldn't hurry to create all the threads joinable, however, because this has a disadvantage as well: youmust Wait() for a joinable thread or the system resources used by it will never be freed, and you also must delete the correspondingwxThread object yourself if you did not create it on the stack. In contrast, detached threads are of the "fire-and-forget" kind: you only have to start a detached thread and it will terminate and destroy itself.”最近翻Qt编程的艺术英语水平大增啊,看这个感觉不怎么费力气了都O(∩_∩)O~~virtual ExitCode wxThread::Entry()
这个Entry()是线程的执行部分,我们把想要执行的都写在里面,里面的都是主要业务
比如CHTTPDownloadThread::Entry(),117行,够长吧!这个函数主要完成了HTTP下载功能
下面的问题是,在什么情况下需要创建CHTTPDownloadThread来下载东西呢?
有了Cscope,这个问题不难解决
我们看到第21项,amule就创建了这么一个线程来检查最新版本
第一次看的这么深入,还看到了作者的注释,纪念一下:
作者:maxiee 发表于2013-8-22 13:56:12 原文链接
阅读:46 评论:0 查看评论