在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)的更多相关文章

  1. 线程安全 Thread Safety Problem scala concurrency 并发

    小结: 1.基于java并发模型 Scala concurrency is built on top of the Java concurrency model. 2. 将每个请求放入一个新的线程 T ...

  2. Thread Safety线程安全

    Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分 如果disabled就选择nts(php_stomp-1.0.9-5.5-nts-vc11-x86.zi ...

  3. clang的线程安全分析模块 thread safety analysis

    介绍 Clang的线程安全分析模块是C++语言的一个扩展,能对代码中潜在的竞争条件进行警告.这种分析是完全静态的(即编译时进行),没有运行时的消耗.当前这个功能还在开发中,但它已经具备了足够的成熟度, ...

  4. Thread Safety in Java(java中的线程安全)

    Thread Safety in Java is a very important topic. Java provide multi-threaded environment support usi ...

  5. 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 ...

  6. python3 线程 threading.Thread GIL性能详解(2.3)

    python3 线程 threading 最基础的线程的使用 import threading, time value = 0 lock = threading.Lock() def change(n ...

  7. java并发编程学习: 守护线程(Daemon Thread)

    在正式理解这个概念前,先把 守护线程 与 守护进程 这二个极其相似的说法区分开,守护进程通常是为了防止某些应用因各种意外原因退出,而在后台独立运行的系统服务或应用程序. 比如:我们开发了一个邮件发送程 ...

  8. Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别

    一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...

  9. Effective Java 70 Document thread safety

    Principle The presence of the synchronized modifier in a method declaration is an implementation det ...

随机推荐

  1. Vs2012于Linux应用程序开发(4):公共财产的定义

    在嵌入式开发流程.有些参数基本上不改变,比如编译主机IP,username,password等参数.我们用VS提供的属性管理器来保存这些參数. 打开属性管理器: watermark/2/text/aH ...

  2. pygame系列_游戏中的事件

    先看一下我做的demo: 当玩家按下键盘上的:上,下,左,右键的时候,后台会打印出玩家所按键的数字值,而图形会随之移动 这是客观上面存在的现象. 那么啥是事件呢? 你叫我做出定义,我不知道,我只能举个 ...

  3. 【C/C++】BinarySearch

    /* * BinarySearch.c * * Created on: 2014年6月25日 * Author: wenbo */ #include <stdio.h> int binar ...

  4. [Unity3D]Unity3D持久性数据的游戏开发PlayerPrefs采用

    大家好,我是秦培,欢迎关注我的博客,我的博客地址">blog.csdn.net/qinyuanpei. 博主今天研究了在Unity3D中的数据持久化问题.数据持久化在不论什么一个开发领 ...

  5. 关于bind函数和connect函数的测试结论

    1. 一般客户端不用绑定,系统给你自动分配(有些ip不是固定的,bind也不是一个好方法):而服务器需要绑定,因为需要给客户端一个众所周知的固定的地址: 2. 关于bind错误,可以用WSAGetLa ...

  6. 使用C++名单在文档处理和学生成绩管理系统相结合

    对于学生成绩管理系统,我并不陌生,几乎学习C人的语言.做项目会想到学生成绩管理系统,我也不例外.在研究中的一段时间C语言之后,还用C语言到学生管理系统,然后做几个链接.计数,这个系统是以前的系统上的改 ...

  7. 【Web优化】Yslow优化法则(四)启用Gzip压缩

    Yslow的第4个经验法则指出:启用gzip压缩功能,能够降低HTTP传输的数据和时间,从而降低client请求的响应时间. 本篇是Yslow法则的第四个,主要包含三个方面的内容: 1.      什 ...

  8. AndroidUI组件之ListView小技巧

    android:fadingEdge="none"//出去黑影  android:listSelector="@android:color/transparent&quo ...

  9. jvm调音

    jvm性能调优的目地:1)控制jvm的堆栈大小.比方当你的程序年轻代对象在某个时间段产生的比較多的时候,就须要控制年轻代的堆大小. 同一时候还要控制总的JVM大小避免内存溢出 2)控制GC的行为. G ...

  10. 使用WPF创建无边框窗体

    一.无边框窗口添加窗口阴影 实际上在WPF中添加无边框窗口的窗口阴影十分简单. 首先,设置WindowStyle="None"以及AllowsTransparency=" ...