0、章节引用
1、课程目标
- 线程概念(了解)
- 线程特点(了解)
- 线程创建(熟练)
- 小结
2、进程
- 进程是为了执行程序分配的总称,进程创建会分配一下资源(内存资源,CPU资源等)。
- 每一个进程有自己独立的地址空间,代码、数据,互不影响。
- Linux为每一个进程创建task_struct(任务结构体,在内核创建)
- 每一个进程都参与内核调度,互补影响
3、线程
- 进程在切换时系统开销大(内存的读写速度比CPU处理的速度慢。CPU会出现等待读写进程指令的现象,为了解决这个问题出现了cache。cache是位于CPU和主存储器DRAM之间的一块高速缓冲存储器,规模较小,但是速度很快,将cache放置在CPU和主存之间,作为主存数据的缓存。当CPU试图从主存中加载/存储数据的时候,CPU会首先从cache中查找对应地址的数据是否缓存在cache中,如果数据缓存在cache中,那么直接从cache中拿到数据并返回给CPU)
- 操作系统引入了轻量级进程LWP
- Linux不区分进程、线程,都是任务,需要CPU执行。
4、线程特点
- 线程指的是共享相同的地址空间的多个任务
- 线程的好处
- 1)大大提高任务切换的效率
- 2)避免额外的TLB和cache的刷新。
5、线程共享资源
- 一个进程的多个线程共享的资源
- 1)可执行的指令
- 2)静态数据
- 3)进程中打开的文件描述符
- 4)当前工作目录
- 5)用户ID
- 6)用户组ID
6、线程私有资源
- 每一个线程私有的资源
- 1)线程ID(TID)
- 2)PC(线程计数器)和相关寄存器
- 3)堆栈
- 4)错误号
- 5)优先级
- 6)执行状态和属性
7、Linux线程库
- pthread线程库提供如下的基本操作
- 1)创建线程
- 2)回收线程
- 3)结束线程
- 同步和互斥机制
- 1)信号量
- 2)互斥锁
8、线程创建-pthread_create
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
- 返回值,函数执行成功返回0,失败返回错误码
- 参数1thread 为线程对象
- 参数2attr为结构体指针,执行线程的属性。默认属性为NULL
- 参数3start_routine为线程执行函数
- 参数4arg为线程函数的参数,没有参数为NULL
9、线程回收-pthread_join
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
- 返回值,函数执行成功返回0,失败返回错误码
- 参数1thread 为线程对象
- 调用回收线程函数若线程没有结束,则该函数会阻塞,直到线程结束才会回收正常。
- 参数2*retval接受线程的返回值
10、线程回收-pthread_exit
#include <pthread.h>
void pthread_exit(void *retval);
- 结束当前线程,在线程中不能调用exit/_exit结束线程,因为其会将在整个进程结束,进程结束,则所有线程不会存在。可以只用pthread_exit或者return结束当前进程。
- retval参数可被其他线程通过pthread_join获取。其不能是线程中的地址。
- 线程结束线程私有资源被释放。
11、线程-示例
- 创建线程、在线程中修改全局变量中的字符串。并对线程进行退出和回收。
#include<stdio.h>
#include<pthread.h>
#include <stdlib.h>//exit
#include <string.h>//memcpy
char message[32] = "Hello World";//放在全局中,子进程需要访问
void * thread_func(void *arg)
{
printf("start\n");
strcpy(message,"Linux,Hello!");
pthread_exit("exit pthread");//可以返回字符串
//pthread_exit((void *)(123));//可以返回数值,数值类型和函数返回类型一致
//return (void *)123;
}
int main(void)
{
int ret;
pthread_t a_thread;
void *result;
if(pthread_create(&a_thread,NULL,thread_func,NULL)!=0)
{
printf("创建线程失败。\n");
exit(-1);
}
else
{
//pthread_join(a_thread,result);
ret = pthread_join(a_thread,&result);
printf("ret = %d\n",ret);
printf("result = %s\n",(char *)result);//进程返回字符串时
//printf("result = %d\n",(int *)result);//进程返回数值时
printf("message = %s\n",message);//信息在进程中进行改变
return 0;
}
}
$ gcc pthread_creat_join_exit.c -lpthread
start
ret = 0
result = exit pthread
message = Linux,Hello!
12、线程小结
- pthread_create
- pthread_exit
- pthread_join