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

3 篇文章 0 订阅

本文适合对多线程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.git
cd Thread/src
make

然后编译链接自己的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,实时跟踪最新开发进度~

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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值