本文将介绍Linux编程中线程的一些接口使用,分享一些对多线程部分的理解,希望对大家有所帮助。
文章目录
一、线程的基本认识
1.线程是进程内部的一个执行分支。
2.线程是CPU调度的基本单位(CPU调度是通过task_struct去调度的,Linux中并没有真为线程设计task_struct而是复用了进程相关代码来实现的)(如下图)。
3.进程承担分配系统资源的实体,线程是进程内部的一个执行分支。
二、线程的控制(创建线程、分离线程、结束线程...)
1.Linux下编写多线程程序的注意事项
1.编译的时候要加上-lpthread的选项
pthread库是一个外部库,不是Linux系统的内部库。因此,在编译多线程程序时需要显式地告诉编译器去链接pthread库。
如:test_thread:test_thread.cc
g++ -o $@ $^ -lpthread -std=c++11
2.所有接口函数要引入头文件#include<pthread.h>
2.创建线程-pthread_create( )
1.函数原型:2.参数解释:
1.thread为线程ID(创建成功后thread的值就是线程的ID)
2.pthread_attr_t为线程的属性
3.第三个参数为一个函数指针(接收一个函数,可以理解为新线程会执行函数的语句)
4.第四个参数是用于传给第三个函数的形参的(给函数传参用)
3.通过代码来理解
#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
void* new_thread_run(void* args)
{
while(1)
{
cout<<"I am new phread,name is: "<<(char*)args<<endl;
sleep(1);
}
}
int main()
{
//创建线程
pthread_t pid;
//1.线程ID 2.线程处理方式 3.返回值 参数都是void*的函数 4. 传给3中函数的参数
pthread_create(&pid,nullptr,new_thread_run,(void*)"Thread 1");
//主线程
while(1)
{
cout<<"I am main thread!!!"<<endl;
sleep(1);
}
return 0;
}
执行结果为:
分析结果可知:
1.第四个参数的字符串Thread 1被新线程的函数接收且使用了(第四个参数可以用于传参)。
2.可见有两个死循环打印,也就是有两个执行流,我们创建线程成功了。
2.获取线程id-pthread_self( )
1.函数原型:pthread_t pthread_self(void);
2.函数用法:获取调用线程ID(谁调用获取谁的线程ID)
查看的线程id是pthread库中的id不是linux内核中的LWP
#include<iostream>
#include<pthread.h>
using namespace std;
void* new_thread(void* args)
{
cout<<"new pthread ID: "<<pthread_self()<<endl;
return nullptr;
}
int main()
{
pthread_t tid;
pthread_create(&tid,nullptr,new_thread,nullptr);
cout<<"main pthread ID: "<<pthread_self()<<endl;
return 0;
}
执行结果:
可见打印出来对应的ID。
3.等待线程结束-pthread_join( )
1.函数原型:int pthread_join(pthread_t thread, void **value_ptr);
2.函数参数:thread:线程ID
value_ptr:它指向一个指针,后者指向线程的返回值
返回值:成功返回0;失败返回错误码
4.线程终止-pthread_exit( )
1.函数原型:void pthread_exit(void *value_ptr);
2.函数参数:value_ptr:接收退出信息
#include<iostream>
#include<unistd.h>
#include<pthread.h>
using namespace std;
void* Create_New_Thread(void* agrs) //pthread_create的第四个参数会传给agrs 然后强转agrs进行使用
{
cout<<"I am new_thread,name: "<<(const char*)agrs<<endl;
//return (void*)1234;
pthread_exit((void*)1234); //常用于表示该线程退出返回退出信息1234
}
int main()
{
pthread_t tid;
//1.创建新线程
pthread_create(&tid,nullptr,Create_New_Thread,(void*)"Thread 1");
//2.等待子线程结束
void* ret=nullptr;
//ret存放的是Create_New_Thread返回结果 也就是用于接收线程返回结果
//参数1为: 线程ID 参数2为:void*的变量存储线程返结果(Create_New_Thread)
pthread_join(tid,&ret);
cout<<"main thread get,message: "<<(long long)ret<<endl; //void* 64位下位8字节
cout<<"主进程结束啦!"<<endl;
return 0;
}
执行结果为:
I am new_thread,name: Thread 1
main thread get,message: 1234
主进程结束啦!
由此可知join阻塞等待,本案例中是主线程等待到子线程结束后才退出,且返回值存到了ret中。
pthread_exit()函数可以终止线程并且返回信息。
总结
本文简单分享了一下线程的理解和一些线程编程常用的接口函数的操作,希望可以对大家有所帮助。