【操作系统】自己封装一个简单的线程库

目录

一、整体框架

二、具体实现

1.Thread()

2.void start()

3.void join()

三、使用方法


一、整体框架

#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <pthread.h>

typedef std::function<void *(void *)> func_t;
const int num = 1024;

class Thread
{
private:
    static void *start_routine(void *args)
    {
        Thread *_this = static_cast<Thread *>(args);
        return _this->callback();
    }

    void *callback() { return _func(_args); }

public:
    Thread();
    void start(func_t func, void *args = nullptr);
    void join();
    std::string threadname() { return _name; }

private:
    std::string _name;     // 线程名称
    pthread_t _tid;        // 线程id
    func_t _func;          // 线程要执行的函数
    void *_args;           // 线程要执行的函数 的参数
    static int _threadnum; // 线程编号
};

int Thread::_threadnum = 1;

对static void *start_routine(void *args)函数的解释

① 解释功能:他是线程要执行的start_routine函数【参数void*,返回值void*】

② 为什么要有static?

类内函数有一个默认参数this指针,这就与start_routine函数的参数不匹配了

static修饰的类内函数没有this指针,所以加static就让start_routine函数的参数符合要求了

③ 又引出了一个新的问题:static函数没有this,那他就访问不到类内的回调函数 func_t _func;

首先创建 void *callback() { return _func(_args); } 函数,用callback函数来访问类内回调函数

在给start_routine传参的时候,给他传this指针,通过this找到callback就可以访问回调函数了

总结:实际上真正执行线程的函数是callback,而start_routine只是为了传递this指针

二、具体实现

1.Thread()

Thread()构造函数:给线程起名字

Thread()
{
    char namebuffer[num];
    snprintf(namebuffer, sizeof(namebuffer), "thread-%d", _threadnum++);
    _name = namebuffer;
}

2.void start()

start()启动函数:参数是线程要执行的函数及其参数,负责创建线程

void start(func_t func, void *args = nullptr)
{
    _func = func; // 回调函数
    _args = args; // 回调函数的参数
    int n = pthread_create(&_tid, nullptr, start_routine, (void *)this);
    assert(n == 0);
    (void)n;
}

3.void join()

join()函数负责线程等待

void join()
{
    int n = pthread_join(_tid, nullptr);
    assert(n == 0);
    (void)n;
}

三、使用方法

#include "testthread.hpp"
#include <unistd.h>
#include <string>

void *run(void *args)
{
    std::string message = *static_cast<std::string *> (args);
    while (true)
    {
        std::cout << message << std::endl;
        sleep(1);
    }
    return nullptr;
}

int main()
{
    Thread t1;
    Thread t2;

    std::string msg1 = "thread 1 run"; // 使用 std::string 对象
    std::string msg2 = "thread 2 run";

    t1.start(run, (void *)&msg1); // 传递 msg1 的地址
    t2.start(run, (void *)&msg2); // 传递 msg2 的地址

    t1.join();
    t2.join();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值