重入与线程安全解惑
软件开发工具链一般不会对子程序/函数不可重入或者非线程安全给出错误和警告信息,只有在软件运行中才会出现异常。在具有中断(抢占)系统或并行(并发)处理能力的处理器中,子程序或函数的重入与线程安全性显得格外重要,这是确保多线程系统正确可靠运行的重要基础。先看两个简单但极具代表性的例子。
StaticVariable32 和 StaticVariable64 是多线程共享的全局静态变量。
在下面这个例子中,函数Function32是可重入的。
volatile int32_tStaticVariable32 = 100;
int Function32(int32_t Variable)
{
return (Variable > StaticVariable32) ?(1):(0);
}
在下面这个例子中,函数Function64是不可重入的。
这是因为它不符合本贴附图中规则R6.2“对任何外部静态变量的访问均为原子操作”的要求。
volatile int64_tStaticVariable64 = 100;
int Function64(int64_t Variable)
{
return (Variable > StaticVariable64) ?(1):(0);
}
重入与线程安全性涉及目标处理器的基本架构、指令系统、寻址方式、操作系统以及工具链等相关知识。本文内容仅针对C语言、ARM Cortex-M处理器和KEIL MDK-ARM工具链,旨在明确重入与线程安全的相关概念,以及在应用中如何确保子程序或函数可重入和线程安全的一般规则。
支持一下 多谢分享,学习了下 支持一下,
多谢分享。 除了字体颜色和排版有点辣眼睛,其他都挺好的,多谢楼主 感谢无私奉献! 多谢楼主分享!谢谢! 多谢分享。 用指针操作访问静态变量会不一样? Ray______ 发表于 2019-2-20 09:18
用指针操作访问静态变量会不一样?
这问题问得好。
对ARM Cortex-M 处理器来说,以变量名和指针访问静态变量,它们的共同点如下:
它们的不同点是:以变量名访问,在不同线程中你只能访问同一个对象,而通过指针则可以在不同线程中访问不同对象,这就回避了竞争访问。这也是指针的主要用途之一。 laoshuhunya 发表于 2019-2-20 09:46
这问题问得好。
对ARM Cortex-M 处理器来说,以变量名和指针访问静态变量,它们的共同点如下:
指针操作,不同线程中指向同一个地址的指针也是访问的同一个静态变量 wx-ta 发表于 2019-2-20 10:07
指针操作,不同线程中指向同一个地址的指针也是访问的同一个静态变量
所以说它不能确保可重入,只能保证线程安全(在各个线程中指针指向不同目标的条件下)
学习下,多谢卤煮 没看出来Function64和Function32这两个函数有什么区别啊? 图片太小,手机上看不清图片 好贴,多谢分享~ 红色和洋红色,在这个背景下,对我来说,都是辣眼睛的。看着累。 lsn_tj 发表于 2019-2-20 13:01
没看出来Function64和Function32这两个函数有什么区别啊?
一个是32位一个是64位。32位数据的比较是一条指令就完成了,是原子操作。而64位比较的是多条指令,可以被打断。 lz最近对底层很深入哦,一起学习 security 发表于 2019-2-20 13:49
红色和洋红色,在这个背景下,对我来说,都是辣眼睛的。看着累。
收到。
黑色背景下,可选的字体颜色不多,后面我们会尝试其他方案。为此我给几位眼界颇高的美女看了,她们觉得挺好的{:titter:} myxiaonia 发表于 2019-2-20 14:20
lz最近对底层很深入哦,一起学习
这是C编程中最阴暗隐晦的角落,虽然危机四伏,但也是渡劫成功的必经关口 {:titter:} laoshuhunya 发表于 2019-2-20 14:45
这是C编程中最阴暗隐晦的角落,虽然危机四伏,但也是渡劫成功的必经关口 ...
我在图片上看到了你之前回复我的内容,要写这类文章必须要下功夫,没法乱吹牛的 myxiaonia 发表于 2019-2-20 15:46
我在图片上看到了你之前回复我的内容,要写这类文章必须要下功夫,没法乱吹牛的 ...
代码重入问题牵扯的面比较大,春节刚好有空把思路整理总结下
laoshuhunya 发表于 2019-2-20 14:35
收到。
黑色背景下,可选的字体颜色不多,后面我们会尝试其他方案。为此我给几位眼界颇高的美女看了,她 ...
{:lol:}几位 眼界颇高的美女……
偶觉得是不是应该分享美女图{:shy:} flamma 发表于 2019-2-20 13:58
一个是32位一个是64位。32位数据的比较是一条指令就完成了,是原子操作。而64位比较的是多条指令,可以被 ...
打断对线程的运行本身有什么影响呢?因为都是对静态变量的读取,就算被打断了也不会影响读出来的值吧 这种背景花里胡哨的东东,看的真累。
多谢楼主分享!谢谢! flamma 发表于 2019-2-20 13:58
一个是32位一个是64位。32位数据的比较是一条指令就完成了,是原子操作。而64位比较的是多条指令,可以被 ...
多谢指教。再请教一下,这个问题也要看CPU是多少位的吧? qq78929709 发表于 2019-2-20 16:36
打断对线程的运行本身有什么影响呢?因为都是对静态变量的读取,就算被打断了也不会影响读出来的值吧 ...
这不是在讨论线程安全吗,比如只比较了一半,被高优先级的线程打断,把这个值改掉了。程序的返回值可能和设计时的考虑不一样了。 lsn_tj 发表于 2019-2-20 19:08
多谢指教。再请教一下,这个问题也要看CPU是多少位的吧?
是的。这里讨论的是ARM Cortex-M。什么是原子操作和CPU的位数和指令架构都有关系。 laoshuhunya 发表于 2019-2-20 09:46
这问题问得好。
对ARM Cortex-M 处理器来说,以变量名和指针访问静态变量,它们的共同点如下:
变量名和指针并没有本质区别,变量名不让用是因为编译器认为变量名称的作用域不够吧。 icoyool 发表于 2019-2-21 14:56
变量名和指针并没有本质区别,变量名不让用是因为编译器认为变量名称的作用域不够吧。 ...
要在某个班级里面找到某位学生可以叫她名字,也可以喊她的座号。名字和座号都对应某个人,但名字和座号显然是不同的。在一个班级里面,座号具有唯一性,名字则可能有重名。而在一所学校里,座号将不再唯一,不同的班级有同样的座号。所以,座号的唯一性只在班级里有效,或者说,它的作用域是班级。在计算机系统中,变量名和指针的关系大体与此类似。
可以看下《指针解惑》,虽然排版不是太好看,但里面的每一句话都不是多余的,有关指针的问题几乎都能在那里找到答案。 感谢分享学习了 多谢分享。 楼主玩的太高深了。目前只是关注临界变量的原子操作问题。 谢谢分享! laoshuhunya 发表于 2019-2-20 14:35
收到。
黑色背景下,可选的字体颜色不多,后面我们会尝试其他方案。为此我给几位眼界颇高的美女看了,她 ...
虚拟世界实验室 楼主有网站链接? huangqi412 发表于 2019-3-12 15:39
虚拟世界实验室 楼主有网站链接?
世界是虚拟的,实验室也是虚拟的~~~
页:
[1]