-
线程的概念
1.什么是线程?
线程是cpu进行调度的基本单位,简单的来说,线程就是进程里面的进程,不过线程共享了进程的虚拟地址空间,而且公用了进程的代码段和数据段,线程是进程里面的一个执行流(cpu调度的基本单位是线程,线程是真正执行一段程序的执行单位),所以有的人说线程是运行在进程上面的。
2.进程和线程的区别
(1)进程是资源竞争的基本单位
(2)线程是cpu运行调度的基本单位
(3)线程共享进程的一部分数据:文件描述符(文件状态信息)—>每种信号的处理方式—>当前工作目录—>用户id和组id
(3)但是线程也有自己独立的一部分数据:—>线程id—>上下文数据—>栈—>error—>信号屏蔽字—>调度优先级
3.线程相对进程的优点——因为公用程序虚拟地址空间
(1)创建一个线程相对于进程所需的代价更小
(2)相对于进程间的切换相比,线程之间的切换需要操作系统做的工作更少
(3)线程所占用的资源比进程少很多,创建销毁代价小
(4)充分利用多处理器的可并行数量
(5)在IO等待时,程序可以执行其他操作
4.线程的缺点
(1)因为线程间通信更加方便,使用同一块虚拟地址空间,缺少访问控制,在编码时考虑的更加复杂,要考虑对数据的安全访问
(2)稳定性低,异常退出时,整个进程都退出,一个线程访问错误整个线程组退出 ,对临界资源的访问不安全 -
线程控制
1.创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
pthread_t 无符号长整型数据,用于获取输出型参数,用于获取用户的线程id
attr 线程属性,设置起来比较麻烦,有一个单独的接口来设置,通常设置为NULL
start_routine 函数指针,线程的入口函数,
arg 参数,传递给线程的参数,通过入口函数传递给线程的参数
返回值 0————是成功
error number————错误返回错误编号
0是成功,非零是失败
- 线程id
pthread_self获取调用线程的线程id
pid——>LWP 轻量级进程
tgid——> PID进程组id
tid 是每个线程的线程程序地址空间
ps -efL | head -n 1 && ps -efL | grep 进程名
LWP:轻量级进程
PID是tgid:是第一个进程的id
NLWP是当前进程有几个线程
查看线程id
tid返回的是同一个虚拟地址空间的地址,每一个线程在虚拟地址空间中有独立的地址空间,有独立的的栈,有独立的数据(相对独立)
3.线程终止
终止方式:
(1)return,但是主线程,main中不能return,其他的普通线程可以return
(2)pthread_exit 谁调用谁退出,退出的是自己
(3)pthread_cancle 终止指定的线程,退出的是别人
函数接口:void pthread_exit(void *value_ptr);
功能:线程终⽌
参数
value_ptr:value_ptr不要指向⼀个局部变量。
返回值:⽆返回值,跟进程⼀样,线程结束的时候⽆法返回到它的调⽤者(⾃⾝)
- 线程的等待:pthread_join
功能:等待指定线程的退出
线程创建出来默认joinable状态可执行状态,只有处于joinable状态的线程,才可以被等待。线程退出后,操作系统为了保存退出的返回值,因此操作系统不会直接自动回收资源,需要其他线程等待,获取返回值,并允许操作系统回收资源,否则不等待则会造成资源泄漏。 - 线程的分离:pthread_detach
设置线程的分离属性,被设置的线程,退出后直接自动回收资源,不需要被等待;
如果线程处于detach状态,则线程不能被等待;
分离状态:detach
若线程被取消,返回值是(PTHREAD_CANAELED -1)
如果不是joinable状态,这时候等待报错(EINVAL) - 代码实现创建线程
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void*thr_start(void*arg)
{
// pthread_t tid=(pthread_t)arg;
pthread_t tid=pthread_self();//打印线程id
while(1){
printf("I am common thread!%p\n",tid);
sleep(1);
}
return NULL;
}
int main()
{
pthread_t tid;
int ret=pthread_create(&tid,NULL,thr_start,(void*)999);
if(ret!=0){
printf("pthread creat error\n");
return -1;
}
printf("common thread id:%p\n",tid);
while(1){
printf("I am main thread!\n");
sleep(1);
}
return 0;
}