简介
进程的颗粒度太大,每次都要有调入,保存,调出。如果我们把进程比喻为一个运行在电脑上的软件,那么一个软件的执行不可能是一条逻辑执行的,必定有多个分支和多个程序段,就好比要实现程序A,实际分成a,b,c等多个块组合而成,这里的abc就是线程。在Linux系统中其实没有真正意义上的线程,不和windows系统中一样,windows中的进程和线程有着明确的区分,各有各的数据结构,API等等。在linux中线程就是一种轻量级的进程。
线程的特点
同一进程中的多个线程之间的关系:
共享部分:
1.代码段,数据段;
2.文件描述符表;
3.信号的处理方式;
4.用户id和组id;
线程私有部分:
1.线程id;
2.上下文,包括各种寄存器的值,程序计数器和栈指针;
3.栈空间;
4.环境变量;
5.信号屏蔽字;
6.调度优先字;
线程与进程的区别
进程是最小的资源分配的单位,而线程是cpu独立运行独立调度的基本单位,也就是说线程和进程的最大区别就是他们的颗粒度大小不同,线程的执行粒度更为细小。
线程的控制
线程创建函数
#include<pthread.h>
pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(start_routime)(void *),void *arg);
Compile and link with -pthread
返回值:成功返回0,失败返回错误号。
参数:thread,所创建的线程的ID,创建成功后会把线程id放入到thread的内存单元;
attr,线程的属性;
start_routine:线程所执行的函数,该函数的返回值为void*,参数也为void*,具体类型是由调用者自己定义;
arg,start_routine函数接收一个void*参数,即arg。
终止线程
线程的终止有三种方法,这三种方法只会终止线程不会影响进程。
1.从线程函数return。这种方法对主线程不适用,从main中return相当于exit;
2.调用pthread_cancel终止同一进程中的另一个线程;
3.线程可以调用pthread_exit终止自己,当调用这个函数的时候,线程占用的内存资源并不会随着线程的终止而结束,但可以使用pthread_join()函数来同步并释放资源。
#include<pthread.h>
void pthread_exit(void *retval);
compile and link with -pthread.
返回值为空。
参数:当线程使用exit退出时,retval为调用线程的返回值,可由其他函数例如pthread_join来获取。
线程等待
#include<pthread.h>
int pthread_join(pthread_t thread,void **retval)
complic and link with -pthread
返回值:成功返回0,失败返回错误号;
参数:调用该函数的进程阻塞式等待线程thread所指向的函数执行完毕才继续执行后面的执行流,retval为从线程接收到的返回值。
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
void thread1()
{
int i = 0;
for(;i<3;i++)
{
printf("I am child thread1.\n");
sleep(3);
}
pthread_exit(0);
}
void thread2(pthread_t pthid1)
{
int i = 0;
for(;i<3;i++)
{
printf("I am child thread2.\n");
}
pthread_exit(0);
}
int main()
{
pthread_t pthid1,pthid2;
int ret = 0;
ret = pthread_create(&pthid1,NULL,thread1,NULL);
if(ret != 0)
{
printf("thread creat failed!");
}
pthread_join(pthid1,NULL);//阻塞式等待pthread1线程终止
ret = pthread_create(&pthid2,NULL,thread2,NULL);
if(ret != 0)
{
printf("thread creat failed!");
}
pthread_join(pthid2,NULL);
return 0;
}
运行结果
线程分离
一个线程是可结合的或者是可分离的,一个可结合的线程在被其他线程杀死或者回收之前,它的储存器资源是不会被释放的,一个分离的线程不可以被其他的其他线程终止或者杀死,它所占用的资源只会在它终止时被系统释放。
为了防止线程一直占用系统资源,导致内存泄漏等问题,一个线程默认被设置为可结合的,且每个线程在创建之后要被显示的回收,即pthread_join。或者把线程状态改为可分离的,使其自动回收。
#include<pthread.h>
int pthread_detach(pthread_t thread);
coplic and link with -pthread.
返回值:成功返回0,失败返回错误码;
参数:要分离的进程的ID。