跟我一起用C++实现Java Thread库(一)

来源:互联网 发布:易观国际数据 编辑:程序博客网 时间:2024/05/29 16:19

本文适合对多线程Thread原理比较感兴趣的同学阅读,需要具备一定的C++和Java编程知识。

一、背景

最近学习Java多线程编程,发现Java标准库中的java.lang.Thread接口定义十分友好简洁,使用起来十分方便。不禁想起之前用C/C++写多线程时的烦恼,总会写一些pthread_*函数。于是萌生了这个念头,希望用C++实现一套类似Java Thread的库,简化以后的C++多线程开发。

二、C++ Thread用法

为了最大化地接近java.lang.Thread,同时方便Java开发者快速学习C++ Thread库,本库在使用上与Java完全一致,示例代码为:

#include <iostream>#include <unistd.h>#include <Thread.h>class SimpleThread: public Thread{public:    virtual void run()    {        Thread::run();        std::cout << "I am a Thread\n";        sleep(2);    }    ~SimpleThread()    {        std::cout << "I can free myself\n";    }};int main(int argc, char* argv[]){    SimpleThread *thread = new SimpleThread;    thread->start();    return 0;}

正如你所见,Thread类使用起来十分简洁。你只需要包含Thread.h文件,然后按照Java Thread的用法编写多线程程序就可以了。

代码地址在https://github.com/xhjcehust/Thread.git,文件目录结构为:

.|-- src|   |-- Alias.h|   |-- Exception|   |   |-- BaseException.h|   |   |-- IllegalArgumentException.h|   |   |-- IllegalThreadStateException.h|   |   `-- ThreadCreateFailedException.h|   |-- Makefile|   |-- RefCountable.h|   |-- Runnable.cpp|   |-- Runnable.h|   |-- RunnablePtr.h|   |-- Thread.cpp|   |-- Thread.h|   |-- ThreadEntry.cpp|   |-- ThreadEntry.h|   |-- UnCopyable.h|   |-- _Runnable.h|   `-- _Thread.h`-- test    |-- Makefile    |-- RunnableTest.cpp    |-- SimpleThreadTest.cpp    `-- SyncTest.cpp

使用之前,先进入src文件夹编译生成静态Thread库:

git clone https://github.com/xhjcehust/Thread.gitcd Thread/srcmake

然后编译链接自己的main文件,以上述SimpleThreadTest.cpp文件为例,对应的编译命令为:

g++ -I ../src -o SimpleThreadTest SimpleThreadTest.cpp ../src/Thread.a -lpthread

生成SimpleTest可执行文件,运行效果为:


三、C++ Thread实现

在上面的示例中,我们发现两件有意思的事情:

  • 动态申请的SimpleThread实例不需要释放,内存泄漏?No~

  • 没有pthread_join,主线程为何会等到子线程sleep 2s退出才退出?

先看下Thread库的框架构成:


是的,你没看错,Thread.a调用了你所写的main函数!!!在最后编译生成的文件之中,Main函数事实上被重命名为__Main函数,真正地main函数隐藏在Thread.a之中。这种设计在开发者无感知的情况下将其编写的main函数作为Thread.a的一个模块来执行,其优点在于:

  • 接管main函数所代表的主线程,在main函数执行之后实现资源的清理工作,如join等待子线程执行完成

  • 捕获主线程执行过程中的异常,确保进程不会因为主线程的异常导致其他线程停止

但是,也给开发者带来了一点限制:main函数的声明的格式为:

int main(int argc, char* argv[])

但事实上,这种声明是普遍适用的声明方式,有利于规范平时的编程习惯。 另外,__Main这个符号已经被Thread库所使用,在编写的main文件中也不能使用这个符号,需要重定义。

细心的读者可能发现,示例之中的Thread对象通过new申请堆上内存,而不是栈上分配。主要原因在于C++栈上对象的生命周期在退栈时销毁,而线程内需要引用Thread对象,因此,Thread库限制只能在堆上构造对象,栈上构造会编译出错。

至于SimpleThread实例不需要主动释放这点,在子线程执行完之后,Thread库会自动释放线程申请的Thread对象资源。

四、C++ Thread开发进度

到目前为止,Thread库实现的功能包括:

  • 基础Thread类和Runnable类功能

  • synchronize同步语句块功能

后续需要开发的功能包括:

  • 线程停止,暂停,信号等

  • Thread线程间通信互斥机制

  • 支持线程组等特性。

  • ....

项目地址:https://github.com/xhjcehust/Thread.git如果觉得不错,欢迎fork或star,实时跟踪最新开发进度~

想要获取更多干货?欢迎订阅微信公众号----软件编程之路


原创粉丝点击