线程封装

发布时间 2023-09-13 16:02:37作者: zxinlog

把C语言中的面向过程的线程,在C++中以面向对象的形式进行封装调用。

Thread.h

/*
 * Thread.h
 * Copyright (C) 2023 zxinlog <zxinlog@126.com>
 *
 * Distributed under terms of the MIT license.
 */

#ifndef __THREAD_H__
#define __THREAD_H__

#include <func.h>

#include <iostream>
#include <thread>

class Thread {
public:
    Thread();
    ~Thread();
    void start();
    void join();
    static void *threadFunc(void *arg);
    virtual void run() = 0;

private:
    pthread_t _id;
    bool _isRunning;
};

#endif /* !__THREAD_H__ */

Thread.cc

/*
 *
 * Copyright (C) 2023-09-13 15:40 zxinlog <zxinlog@126.com>
 *
 */
#include <func.h>
#include <pthread.h>
#include <unistd.h>

#include <iostream>

#include "Thread.h"
using std::cout;
using std::endl;

Thread::Thread() {
}

Thread::~Thread() {
}

// 开始线程
void Thread::start() {
    int ret = pthread_create(&_id, nullptr, threadFunc, this);
    if (ret < 0) {
        perror("pthread_create");
        return;
    }
    _isRunning = true;
}

// 结束线程(要调用,否则会段错误)
void Thread::join() {
    if (_isRunning) {
        int ret = pthread_join(_id, nullptr);
        if (ret) {
            perror("pthread_join");
            return;
        }
    }
}

// 线程入口函数
void *Thread::threadFunc(void *arg) {
    Thread *td = static_cast<Thread *>(arg);
    if (td) {
        td->run();
    } else {
        perror("td == nullptr");
    }
    pthread_exit(nullptr);
}

MyThread.cc 测试用

/*
 *
 * Copyright (C) 2023-09-13 15:44 zxinlog <zxinlog@126.com>
 *
 */
#include <func.h>

#include <iostream>

#include "Thread.h"
using std::cout;
using std::endl;

// 线程子类实现run方法
class MyThread : public Thread {
public:
    MyThread(int id)
        : _id(id) {
    }

    void run() override {
        while (1) {
            cout << _id << " thread is runing" << endl;
            sleep(1);
        }
    }

private:
    int _id;
};

void test0() {
    MyThread mt1(1);
    MyThread mt2(2);
    mt1.start();
    mt2.start();

    mt1.join();
    mt2.join();
}

int main(int argc, char *argv[]) {
    test0();
    cout << endl;
    return 0;
}

主要就是线程的开始、结束和线程入口函数,入口函数中调用的真实run,需要在线程子类中进行实现。