目录
线程的创建与等待:
void *threadrun(void *args)
{
int cnt=10;
while(cnt)
{
std::cout<<"new thread run ...cnt:"<<cnt--<<std::endl;
sleep(1);
}
return nullptr;
}
int main()
{
pthread_t tid;
int n=pthread_create(&tid,nullptr,threadrun,(void*)"thread 1");//创建线程
if(n!=0)
{
std::cout<<"create fail"<<std::endl;
return 1;
}
std::cout<<"main thread join begin"<<std::endl;
n=pthread_join(tid,nullptr);//主线程等待
if(n==0)
{
std::cout<<"main thread wait sucess"<<std::endl;//主线程等待成功
}
return 0;
}
主线程需要等待其他线程结束后再退出,避免僵尸进程等情况的出现,线程运行的顺序并不确定,是随机切换的
代码中tid是什么?
tid是一个虚拟地址。
tid并不是内核中的lwp,他是给用户提供的一个ID值。在进程概念中,谈及到库的加载问题,库存储在一个公共区域(共享区,位于栈和堆之间的区域)
- 在内核空间中,动态库加载到共享区中
- Pthread库加载后,在动态库中会为每一个线程分配一个内存块
- 库对线程的管理,创建描述线程的结构体的属性字段,以“数组”的形式管理起来
- struct pthread中保存的是线程在用户级的基本属性
- Linux线程=Linux线程属性集合+LWP
- 每一个线程的中都有独立的栈结构
tid是库中的一个虚拟地址。以pthread_join()函数举例,为什么主线程能够join成功其他线程,这是因为join函数的参数中传入了需要等待的线程的tid值,通过tid找到该线程在库中的位置,进而返回给join 函数
如何看待线程函数传参?
第三个参数不止可以传任意类型,也可以传类对象的地址。
- 当主线程正常运行,但其他线程出现异常,进程会直接终止。因此,线程函数只考虑正确的返回,不考虑异常的情况。
- 线程函数返回不止可以返回任意类型,也可以传递任意对象的地址
创建多线程:
const int num=10;
void *threadrun(void *args)
{
std::string name=static_cast<const char*>(args);
while(true)
{
std::cout<<name<<"is running"<<std::endl;
sleep(1);
}
}
int main()
{
std::vector<pthread_t>tips;
//创建多线程
for(int i=0;i<num;i++)
{
//线程id
pthread_t tid;
char *name=new char[128];
snprintf(name,128,"thread-%d",i+1);
pthread_create(&tid,nullptr,threadrun,name);
}
sleep(100);
终止多线程:
主线程退出代表进程终止。
新线程退出方式:
- 函数return
- exit:在多线程中,任意一个线程调用exit ,进程都会终止,因为exit是终止进程的,线程使用的exit叫做pthread_exit函数
- main thread call pthread_cancel,新线程的退出结果是-1
线程分离:
一个线程被分离,线程的工作状态为分离状态,不需要被join 也不可以被join
C++11多线程
c++11多线程的本质就是对原生线程库接口 的封装
线程封装:
#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>
namespace threadmoudle
{
typedef void (*func_t)(const std::string &name);
class Thread
{
public:
// Thread(const std:string &name,func_t func):_name(name),_func(func)
// {
// }
Thread(const std::string &name, func_t func):_name(name), _func(func)
{
std::cout << "create " << name << " done" << std::endl;
}
void Excute()
{
_func(_name);
}
static void *ThreadRoutine(void *args)
{
Thread *self=static_cast<Thread*>(args);//获取当前对象
self->Excute();
return nullptr;
}
bool start()
{
int n=::pthread_create(&_tid,nullptr,ThreadRoutine,this);
if(n!=0)return false;
return true;
}
std::string status()
{
if(_isrunning)return "thread run";
else
return "thread stop";
}
void stop()
{
if(_isrunning)
{
pthread_cancel(_tid);
_isrunning=false;
}
}
void join()
{
if(!_isrunning)
{
pthread_join(_tid,nullptr);
}
}
std::string name()
{
return _name;
}
~Thread()
{
}
private:
std::string _name;
pthread_t _tid;
bool _isrunning;
func_t _func;//线程执行的回调函数
};