线程安全与可重入函数
来源:互联网 发布:外国法制史 知乎 编辑:程序博客网 时间:2024/06/05 09:10
线程安全
一个函数称为线程安全的,当且仅当被多个并发线程反复调用时,它会一直产生正确的结果。
线程安全问题主要是由全局变量和静态变量引起的。
如果每个线程对全局变量,静态变量只有读操作,没有写操作。一般来说这个全局变量是线程安全的。当多个线程同时执行写操作,要保证线程安全,一般就要保证线程的同步问题。
因为全局变量引起的线程安全
#include<stdio.h>#include<pthread.h>int num=0;void* fun(){ int i=0; while(i<1000) { int temp=num; printf("thread is:%u,g_val:%d\n",pthread_self(),num); num=temp+1; i++; }}int main(){ pthread_t id1,id2; pthread_create(&id1,NULL,fun,NULL); pthread_create(&id2,NULL,fun,NULL); pthread_join(id1,NULL); pthread_join(id2,NULL); printf("%d\n",num); return 0;}
这里的结果并不是1000,而且多次运行结果也不一样。两个线程对于一个全局变量的操作不是原子的,两个线程操作同一块代码顺序是不可预期的。
可重入函数
可重入函数是线程安全的一类。函数被不同的控制流程调用时,有可能在第一次调用时还没返回时就再次进入该函数,称为重入。
一个程序main函数调用insert函数向一个链表中插入一个节点,插入需要两步,新节点temp,当前节点cur,temp->next=cur和head=temp两步操作。当只进行了第一步时,因为硬件中断使得进程切换到内核态,再次回到用户态时检测到有信号要处理,于是执行了这个信号,也是调用insert函数插入节点,插入成功后返回到内核态,再次返回到用户态就继续往下执行,刚开始做了一步的插入操作就被打断。最后插入了两个节点,却只有一个节点真正的插入进去了。像这种函数称为不可重入函数,insert访问的是一个全局链表,因为重入而错乱。反之,一个函数之访问自己的局部变量或参数,称为可重入函数
两者比较
1.线程安全是在多线程的情况下引发的,可重入函数时一个线程
2.线程安全不一定是可重入的,但可重入一定是线程安全的
3.如果一个函数由全局变量,这个函数的线程不是线程安全也不是可重入的。
4.如果一个函数当中的数据有自身的栈空间,则这个函数是线程安全且是可重入函数。
5.如果对临界资源的访问加锁,则这个函数是线程安全的。但如果这个重入函数锁未释放就会产生死锁,则是不可重入的。
6.线程安全能够使不同的线程访问同一块地址空间,可重入要求不同的执行流对数据的操作互不影响的结果相同。
- 线程安全与可重入函数
- 线程安全与可重入函数
- 可重入函数与线程安全
- 可重入函数与线程安全
- 线程安全与可重入函数
- 可重入函数与线程安全
- 可重入函数与线程安全
- 可重入函数与线程安全
- 可重入函数与线程安全
- 线程安全与可重入函数
- 线程安全与可重入函数
- 线程安全与可重入函数
- 线程安全与可重入函数
- 可重入函数与线程安全
- 线程安全与可重入函数
- 线程安全与可重入函数
- 线程安全与可重入函数
- 线程安全与可重入函数
- 查询数据库中重复记录的方法
- android binder机制---native获取ServiceManager
- git版本库的工作区 暂存区
- 二、Mac下Appium环境搭建
- 计算灰度图的像素直方图,并显示(c++)
- 线程安全与可重入函数
- C与C++的区别
- 【Hash】自己对于一种字符串hash的证明(?)
- 2017Android面试回忆录「上」(腾讯/阿里/滴滴/美团...)
- 区分 wait() sleep()
- ReentrantLock 源码分析
- 枚举类与注解的知识点梳理与代码演示
- C#——语言基础——数组
- 如何将项目发布到Tomcat的webapps目录下