首页 > 编程知识 正文

什么是线程安全,怎样实现线程安全,什么是线程局部变量ThreadLocal

时间:2023-05-05 05:10:08 阅读:215416 作者:4811

一、线程的基本概念
1、什么是线程:程序中负责执行的哪个东东就叫做线程(执行路线,进程内部的执行序列),或者说是进程的子任务。
2、线程与进程的区别
进程是一个资源单位,而线程是它的一部分。
线程它是轻量级的(只有栈),没有自己独立的内核资源、共享进程的代码段、数据段、堆、环境变量表、命令行参数、文件描述符、信号处理方式、当前工作目标、用户ID、组ID等资源,除了栈,其它都共享进程的。
3、一个进程至少要有一个线程(主线程),也可以有多个线程(可以创建子线程)。

二、基本特点
1、线程是进程的一个实体,是系统独立调度和分派的基本单位。
2、线程有不同的状态,系统提供了多种线程的控制原语,如创建线程、取消线程、销毁线程等。
3、线程之间的不需要类似于IPC的机制进行数据交换,因为他之间是共享的,但新的问题是如何解决同时访问时的冲突。
4、每个线程有自己独立的线程ID、寄存器信息、函数线、错误码。
5、一个进程可以多个线程它们是并发执行(感觉上是),它们可以执行相同的代码也可以执行不同的代码。
6、当需要同时解决多个任务,而这些任务量不大,相互之间可能需要有大量的数据交换,这种情况就不太适合多进程了,而多线程会比较合适,相比于进程线程的系统开销小,任务切换快。

三、POSIX线程
早期的UNIX、Linux系统是不支持线程,而随着计算机技术发展,windows系统中实现的线程的使用,随后UNIX、Linux也都可以使用线程了。
刚开始时都是各个计算机厂商自己私有提供的线程库(用进程模拟的),接口和实现的差异非常大,不易于移植。
于1995年IEEE协会制定IEEEPOSIX1003.1c标准,规定了统一的线程编程接口,遵循该标准的线程实现方式被统称为POSIX线程,即pthread。
线程是以库的形式提供的,编译时需要添加 -lpthread 参数。

四 、线程函数
1、创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
功能:创建一个线程
thread:获取线程id
attr:设置线程属性
start_routine:线程的入口函数
arg:传给线程的参数

案例中的main函数就是所谓的主线程,main函数结束即主线程结束,主线程结束就是进程结束,进程一旦结束所有的线程就都结束了。

2、创建线程时传递参数
由于创建线程可以传递一个void指针,因此只需把要传递的数据的首地址给线程入口函数即可,但在线程入口函数中需要把把void指针转换成对应的类型才能使用。

在线程执行期间,线程之间共享的数据要保证有效,否可能会有段错误、脏数据。

3、等待线程
int pthread_join(pthread_t thread, void **retval);
功能:等待指定的线程结束
thread:要等待的线程id
retval:线程结束时的返回值

注意:
1)、一旦调用就会进入阻塞,会等待线程结束才返回,如果等待的线程不存在,就立即返回。
2)、在等待线程结束时可以获取到线程入口函数的返回值,返回值是指针,因此需要使用二级指针来接收,当线程时要保证线程返回的指针指向的数据依然有效。 3)、如果线程返回的指针指向的是堆内存,则接收到该指针后要进行释放(谁定义谁释放,谁知道该释放谁释放)。

4、获取线程自身的ID
pthread_t pthread_self(void);
功能:获取当前执行线程的ID,与getpid功能类似。

5、比较两个线程ID
int pthread_equal(pthread_t t1, pthread_t t2);
功能:是比较两人个线程ID是不是同一个线程。
注意:为什么定义函数,而不直接使用==,原因有些系统的pthead_t是以结构体形式实现的。

6、线程的终止
1)、从线程的入口函数中return
2)、调用pthread_exit函数
void pthread_exit(void *retval);
功能:立即结束当前线程,如果在主线程中直接结束,相当于结束整个进程。
retval:给pthread_join函数的返回值,相当于线程入口函数的return。

什么不使用exit函数退出?
exit功能是让进程结束,进程中的任何一个线程调用exit都会导致整个进程结束。

7、线程的执行轨迹
同步方式:创建线程之后,主线程可以调用pthread_join函数等待。
异步方式:创建线程之后,就和主线程没有关系,不能被等待。
默认创建出的线程是同步方式执行,可以调用pthread_detach函数使线程分离。

int pthread_detach(pthread_t thread);
功能:分离指定的线程
thread:被分离的线程ID

8、取消线程
取消线程就是主线程或父线程向子线程发送结束请求。

int pthread_cancel(pthread_t thread);
功能:向指定的线程发送取消请求

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。