目录
1 理解Linux的进程相关的函数
2 POSIX线程库的函数介绍
2.1 创建线程
2.2 pthread_ create函数:线程ID及进程地址空间布局
2.3 线程终止
pthread_exit()函数
pthread_cancel函数--主线程终止其它线程
2.4 线程等待
2.5 线程分离
3 如何理解线程库
#include
using namespace std;
#include
#include
#include
void *threadRun(void *args)
{
while (true)
{
cout << "new thread run ..." << endl;
sleep(1);
}
}
int main()
{
pthread_t t;
int ret = pthread_create(&t, nullptr, threadRun, nullptr);
if (ret != 0)
{
cerr << "errno:" << ret << ": " << strerror(ret) << endl;
}
while (true)
{
cout << "main thread run ..." << endl;
sleep(1);
}
return 0;
}
pthread_t pthread_self(void);
pthread_t 到底是什么类型呢?取决于实现。对于Linux目前实现的NPTL实现而言,pthread_t类型的线程ID,本质就是一个进程地址空间上的一个地址。
如果需要只终止某个线程而不终止整个进程,可以有三种方法:
需要注意,pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。
调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:
【多线程并行计算多个累加值】
#include
#include
using namespace std;
#include
#include
#include
#define NUM 5
struct ThreadData
{
ThreadData(int top,int result,const string& name)
:_top(top)
,_result(result)
,_name(name)
{}
int _top;
int _result;
string _name;
int status=0;
};
void *threadRun(void *args)
{
ThreadData*td=(ThreadData*)args;
for(int i=1;i<=td->_top;++i)
{
td->_result+=i;
}
return td;
}
int main()
{
pthread_t t[NUM];
for(int i=0;i(ret);
if (args->status == 0)
{
cout << args->_name << " count [1," << args->_top << "] = " << args->_result << endl;
}
delete args;
}
cout<<"all thread quit!"<
int pthread_detach(pthread_t thread);
可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离:
pthread_detach(pthread_self());
joinable和分离是冲突的,一个线程不能既是joinable又是分离的。
#include
#include
#include
#include
#include
void *thread_run(void *arg)
{
pthread_detach(pthread_self());
printf("%s\n", (char *)arg);
return NULL;
}
int main(void)
{
pthread_t tid;
if (pthread_create(&tid, NULL, thread_run, "thread1 run...") != 0)
{
printf("create thread error\n");
return 1;
}
int ret = 0;
sleep(1); // 很重要,要让线程先分离,再等待
if (pthread_join(tid, NULL) == 0)
{
printf("pthread wait success\n");
ret = 0;
}
else
{
printf("pthread wait failed\n");
ret = 1;
}
return ret;
}
问题:如何理解每一个线程都有自己的线程ID、一组寄存器、栈?
答:一个进程中有着多个线程,而线程的创建是由pthread动态库来创建的,这么多的线程,也是需要管理的,所以pthread库来对它们进行管理!要管理,就要先描述,在组织!--》pthread库会在进程地址空间的共享区中对每一个进程创建一个类似的TCB的结构体!每一个线程的结构体,像“数组”似得聚合到共享区中,此时每一块的结构体的首地址就是每一个线程所对应的线程ID;在结构体内部,会有着自己线程栈的结构--因为栈的数据是由一组寄存器esp,ebp所维护的,在CPU调度不同的线程的时候,每一个线程所对应的esp,ebp里的数值不同,这样就可以准确的切换线程了。
所有线程都需要有自己独立的栈结构,主线程用的是进程系统栈,新线程用的是库中提供的栈结构!