折返(Reentrancy)VS线程安全(Thread safety)
在Wiki上,折返例如,下面的定义(接)
In computing, a computer program or subroutine is called reentrant if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations
complete execution. The interruption could be caused by an internal action such as a jump or call, or by an external action such as a hardware interrupt or signal. Once the reentered invocation completes, the previous invocations will resume correct execution.
翻译过来,就是说在函数运行的过程中。假设发生了中断被迫运行其他动作。其中断运行完毕后(中断运行过程中可能会再次调用该函数)。再次又一次返回函数的时候。可以恢复正确的运行过程。
显然。定义里面并没有强调必须是多线程,并且wiki上也进一步说明了一个事实
This definition originates from single-threaded programming environments where the flow of control could be interrupted by a hardware interrupt and transferred to an interrupt service routine
(ISR).
简单翻译。可重入的定义是依据单线程,而且控制流能够被硬件中断打断的环境的。因此普通情况下并没有涉及和考虑到多线程的情况。
我们再来看看线程安全的wiki定义(具体链接)
Thread safety is a computer programming concept applicable in the context of multi-threaded programs. A piece of code is thread-safe if it only manipulates shared data structures in a manner
that guarantees safe execution by multiple threads at the same time. There are various strategies for making thread-safe data structures.
简单翻译,线程安全就是保证多线程同一时候运行函数时,可以以保证安全运行的情况下操作共享数据。
这里强调了运行的上下文必须为多线程环境。
从以上两个概念的定义我们能够看到。可重入并不一定是线程安全,线程安全也并不一定是可重入的。在这里,能够举两个样例来说明
首先,是一个可重入但不是线程安全的样例。
下面代码段里。把局部变量s保留了全局变量t的状态,可以在中断发生之后恢复原来运行状态。符合可重入的定义。但非常明显。因为无法确保全局数据的一致性(没加锁)。因此不是线程安全
int t; void swap(int *x, int *y)
{
int s; s = t; // save global variable
t = *x;
*x = *y; // hardware interrupt might invoke isr() here!
*y = t;
t = s; // restore global variable
} void isr()
{
int x = 1, y = 2;
swap(&x, &y);
}
然后是一个线程安全但不是可重入的样例。因为对静态变量counter的訪问之前都相互排斥锁进行同步,因此是线程安全的。但假设获取了相互排斥锁,没有释放锁的过程里。发生了中断,这时候假设在中断里再次调用函数,则会发生死锁。因此不是可重入的。
#include <pthread.h> int increment_counter ()
{
static int counter = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&mutex); // only allow one thread to increment at a time
++counter;
// store value before any other threads increment it further
int result = counter; pthread_mutex_unlock(&mutex); return result;
}
由以上两个样例里,更加清晰地说明了两者之间并不一定相互决定的关系。一般来说,实现可重入要注意在函数运行过程中。假设要保存运行进度的状态,要考虑把状态保存到局部变量(栈),TLS。不能保存在全局或者静态变量,另外还要注意不能调用其他不可重入的函数。
最后。经过在网络上的一些调查搜索,发现了部分人对可重入有第二种理解。
简单来说,就是可重入也包含多线程的情况,也就是说当单一线程在函数运行过程中。会保证当另外线程运行的正确性。
也就是可重入包含了对单线程的重入和多线程的重入,显然后者有更强的限定性,同时也保证线程安全。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
折返(Reentrancy)VS线程安全(Thread safety)的更多相关文章
- 线程安全 Thread Safety Problem scala concurrency 并发
小结: 1.基于java并发模型 Scala concurrency is built on top of the Java concurrency model. 2. 将每个请求放入一个新的线程 T ...
- Thread Safety线程安全
Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分 如果disabled就选择nts(php_stomp-1.0.9-5.5-nts-vc11-x86.zi ...
- clang的线程安全分析模块 thread safety analysis
介绍 Clang的线程安全分析模块是C++语言的一个扩展,能对代码中潜在的竞争条件进行警告.这种分析是完全静态的(即编译时进行),没有运行时的消耗.当前这个功能还在开发中,但它已经具备了足够的成熟度, ...
- Thread Safety in Java(java中的线程安全)
Thread Safety in Java is a very important topic. Java provide multi-threaded environment support usi ...
- Java Concurrency In Practice -Chapter 2 Thread Safety
Writing thread-safe code is managing access to state and in particular to shared, mutable state. Obj ...
- python3 线程 threading.Thread GIL性能详解(2.3)
python3 线程 threading 最基础的线程的使用 import threading, time value = 0 lock = threading.Lock() def change(n ...
- java并发编程学习: 守护线程(Daemon Thread)
在正式理解这个概念前,先把 守护线程 与 守护进程 这二个极其相似的说法区分开,守护进程通常是为了防止某些应用因各种意外原因退出,而在后台独立运行的系统服务或应用程序. 比如:我们开发了一个邮件发送程 ...
- Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别
一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...
- Effective Java 70 Document thread safety
Principle The presence of the synchronized modifier in a method declaration is an implementation det ...
随机推荐
- HDU 1253-大逃亡(裸-DBFS)
G - 胜利大逃亡 Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit St ...
- Mac OS X在建筑Python科学计算环境
经验(比如这篇日志:http://blog.csdn.net/waleking/article/details/7578517).他们推荐使用Mac Ports这种软件来管理和安装全部的安装包.依照这 ...
- Ubuntu 14.4 使用中遇到的问题汇总
1.java程序字体问题. 基本的原因是openjdk的缘故 下载最新的jdk安装,地址:http://www.oracle.com/technetwork/java/javase/downloads ...
- 设计模式六大原则(4):接口隔离原则(Interface Segregation Principle)
接口隔离原则: 使用多个专门的接口比使用单一的总接口要好. 一个类对另外一个类的依赖性应当是建立在最小的接口上的. 一个接口代表一个角色,不应当将不同的角色都交给一个接口.没有关系的接口合并在一起,形 ...
- UVALive - 4621 Cav 贪心 + 分析
题目大意:有一张洞穴地图,要在这个洞穴里面存放水,要求水不能碰到洞穴顶部.如今给出每一个位置的顶部位置和地面高度.问最多能够放多少水 解题思路:根据物理定理,每一段有水的连续区间,水位高度必须相等 所 ...
- Deploy 11.2.0.3 RAC+DG on Windows 2008 R2 Step by Step
环境规划: 节点1: tc1 192.168.56.101 内存:2G 节点2: tc2 192.168.56.102 内存:2G 物理备库:tcdg192.168.56.108内存:1.5G 操作系 ...
- 【从翻译mos文章】在OGG (Oracle GoldenGate) 正在使用SCHEMATRANDATA如果,需要额外的db patch
在OGG (Oracle GoldenGate) 正在使用SCHEMATRANDATA如果.需要额外的db patch 参考原始: Patches needed to support SCHEMATR ...
- 编C语言单元测试框架CUnit方法库
/********************************************************************* * Author : Samson * Date ...
- 二分图行列匹配---> hdu2119,hdu1498
hdu2119 题意:给定一个矩形方格,每个格子里面的数字是0或者1,每次操作可以把一整行或列的1变成0,问最少多少次操作能将1全部变为0 一次可以消除某一行或者某一列的1但是可以这么想,最多有多少个 ...
- C#访问MySQL数据库(winform+EF)
原文:C#访问MySQL数据库(winform+EF) 以前都是C#连接SQLServer,现在MySQL也比较火了,而且是开源跨平台的,这里连接使用一下,主要是体会一下整个流程,这里使用的是winf ...