线程
1.线程
线程是程序执行时的一个实例,即它是程序已经执行到何种程度的数据结构的汇集。从内核的观点来看,进程的目的就是担当分配资源(CPU时间、内存等)的基本单位。线程是进程的一次执行过程,也就是一个执行流, 是CPU调度和分派的基本单位,它是比进程更小的能够独立运行的基本单位,即进程是分配资源的最小单位,线程的CPU调度的最小单位。一个进程可以由多个线程组成,线程与同属一 个进程的其他线程共享进程拥有的所有资源。
进程是分配资源的最小单位,线程是CPU调度的最小单位一个进程中创建的线程也是有限的安线程完整手册,当使用线程函数编译程序时要加上外部库文件-lpthread
sudo apt-get install manpages-posix manpages-posix-dev
2.线程的创建
#include <pthread.h>
函数原型:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
功能:创建一个线程
参数:
thread: 线程id号
attr : 线程创建时的属性,如果为NULL 默认属性
start_routine: 线程处理函数 线程的动作执行在函数中
arg : 线程处理函数的参数
返回值:成功返回0,会创建一个线程,失败返回错误码,线程不会创建
#include <pthread.h>
#include <stdio.h>
//线程处理函数
void *threadHandle(void *arg){
int num = *(int *)arg;
printf("This is child thread %d\n", num);
}
//主线程
int main(){
pthread_t pt;
int num = 100;
//整数传参,如果不传参第四个参数为NULL即可
if(0 != pthread_create(&pt, NULL, threadHandle, (void *)&num)){
perror("pthread_create");return -1;
}
printf("This is parent thread\n");
while(1); //线程执行的先后顺序不一定
return 0; //当return之后进程结束,子线程就会结束
}
3.获取线程ID
函数原型:
pthreaf_t pthread_self(void)
功能:获取调用线程的线程号
参数:无
返回值:总是成功
4.线程退出
线程退出有三种情况:
-
- 线程处理函数中程序执行完毕正常退出
- 线程遇到pthread_exit()函数立即退出线程
- 线程执行过程中被同一进程中的其他线程发送取消请求pthread_cancel(),强制退出
如果在主函数中使用pthread_exit函数,会退出在主函数中的主线程,子线程不会退出,进程会等待所有子线程结束后再退出。
void pthread_exit(void *retval);
功能:立即终止调用线程
如果此时该线程为结合态(线程有两种状态、结合态、分离态),就代表需要手动回收资源
此时如果同一进程中的一个线程使用pthread_join阻塞等待该线程结束并为其回收资源
那么pthread_exit的参数就会返回给pthread_join的第二个参数
5.线程回收
一个进程能够创建的线程数是有限的,如果不停的创建线程结束线程但是不回收资源,系统会崩溃
线程的资源回收有两种方式:
手动回收
通过同一进程中的线程调用函数pthread_join()阻塞等待回收另外一个线程的资源
自动回收
使用函数pthread_detach() 将线程设置为分离态,线程结束时系统会为其释放资源
【线程有两种状态、结合态、分离态,默认为结合态】
函数原型:
int pthread_join(pthread_t thread, void **retval);
功能:阻塞等待回收线程id为thread的线程的资源
参数:
thread: 线程号
retval: 子线程退出时候的状态
int pthread_detach(pthread_t thread);
功能:将线程设置为分离态,结束后自动释放
返回值:成功0 失败-1
#include <pthread.h>
#include <stdio.h>
//线程处理函数
void *threadHandle(void *arg){
//pthread_detach(pthread_self()); //将自身设置为分离态
printf("This is child thread\n");
static int a = 100; //延长生命周期
pthread_exit(&a);
}
//主线程
int main(){
pthread_t pt;
int *b;
if(0 != pthread_create(&pt, NULL, threadHandle, NULL)){
perror("pthread_create");return -1;
}
//将子线程设为分离态
//pthread_detach(pt);
printf("This is parent thread\n");
pthread_join(pt, (void **)&b);
printf("b = %d\n", *b);
return 0;
}
6.线程取消
函数原型:
int pthread_cancel(pthread_t thread);
功能:调用该函数的线程给目标线程发送信号,强制其退出
参数:目标线程ID
返回值:成功返回0 失败返回错误码
【调用函数的线程给目标线程发取消请求,目标线程是否响应以及合适响应取决于 是否可被取消状态(该状态由pthread_setcancelstate函数设置)】
函数原型:
int pthread_setcancelstate(int state, int *oldstate);
功能:设置线程是否可被取消(线程默认可以被取消)
参数:
state: 是否能被取消
PTHREAD_CANCEL_ENABLE : 可被取消
PTHREAD_CANCEL_DISABLE : 不可被取消
oldstate: 旧的状态 填NULL
返回值:成功0 失败-1
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
//线程处理函数
void *threadHandle(void *arg){
//pthread_detach(pthread_self()); //将自身设置为分离态
printf("thread start\n");
//将线程设置为不可取消的状态
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
while(1){
printf("thread...\n");
}
printf("thread end\n");
pthread_exit(NULL);
}
//主线程
int main(){
pthread_t pt;
if(0 != pthread_create(&pt, NULL, threadHandle, NULL)){
perror("pthread_create");return -1;
}
sleep(3);
//给子线程发送取消请求
pthread_cancel(pt);
printf("This is parent thread\n");
pthread_join(pt, NULL);
return 0;
}