Linux线程id与简易封装线程实现
线程id
我们发现,线程有个tid和LWP;tid是给用户提供的,是pthread库自己维护的,LWP是内核的,不需要呈现给用户。
站在用户角度上,我们需要的是线程的id,库对线程进行管理,因此会开辟一个内存块(类似大号结构体),tid是一个地址,未来管理线程只要找到线程控制块地址就行(tid)。
线程栈大小是可以调整的,线程属性源码:
typedef struct {int detachstate; // 线程分离状态 (PTHREAD_CREATE_JOINABLE/DETACHED)int schedpolicy; // 调度策略 (SCHED_FIFO/SCHED_RR/SCHED_OTHER)struct sched_param schedparam; // 调度参数int inheritsched; // 继承属性 (PTHREAD_INHERIT_SCHED/PTHREAD_EXPLICIT_SCHED)int scope; // 竞争范围 (PTHREAD_SCOPE_SYSTEM/PTHREAD_SCOPE_PROCESS)size_t guardsize; // 栈保护区域大小void* stackaddr; // 用户指定的栈地址size_t stacksize; // 栈大小
} pthread_attr_t;
linux线程=pthread库中线程属性集+LWP(1:1)
创建轻量级进程:
默认共享地址空间,pthread库就封装了该系统调用,线程属性集合的其实虚拟地址在pthread库中维护。
如果想要全局变量每个线程都私有一份,在变量声明前加__thread(两个_),只在linux中有效,只能修饰内置类型(局部存储)。
简易封装线程库的实现
#pragma
#include<pthread.h>
#include<iostream>
typedef void (*func_t)();
class Thread
{
public:Thread(std::string name,func_t func){this->name = name;this->func = func;}void Excute(){is_running = true;func();}std::string Status(){if(is_running)return "running";elsereturn "sleep";}static void* ThreadRoutime(void* args){Thread *self = static_cast<Thread *>(args);self->Excute();return nullptr;}bool Start(){int n=::pthread_create(&tid, nullptr, ThreadRoutime, this);if(n!=0)return false;elsereturn true;}void Stop(){if(is_running){is_running = false;::pthread_cancel(tid);}}void Join(){if(is_running){::pthread_join(tid, nullptr);}}~Thread(){Stop();}private:std::string name;pthread_t tid;bool is_running;func_t func;
};
使用案例:
#include"Thread.hpp"
#include<iostream>
#include<unistd.h>
using namespace std;
void Run()
{sleep(1);while (1){cout << "this is a thread"<<endl;sleep(1);}
}
int main()
{Thread t("syx", Run);t.Start();cout << t.Status() << endl;sleep(5);t.Stop();cout << t.Status()<<endl;t.Join();return 0;
}