社区
C语言
帖子详情
"线程安全" 和 "可重入" 是一个概念吗?(更正帖子)
see22
2007-05-30 10:33:13
对不起,刚才发错了一个帖子,将“线程安全”写成“信号安全”了,
现在更正:
"线程安全" 和 "可重入" 是一个概念吗? 如果不是,区别在哪里?
...全文
1564
20
打赏
收藏
"线程安全" 和 "可重入" 是一个概念吗?(更正帖子)
对不起,刚才发错了一个帖子,将“线程安全”写成“信号安全”了, 现在更正: "线程安全" 和 "可重入" 是一个概念吗? 如果不是,区别在哪里?
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
20 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
libin1201119
2011-09-07
打赏
举报
回复
上面的例子不是死锁了吗,怎么还叫线程安全,求解释?
zhugcx
2008-09-05
打赏
举报
回复
说一个不可重入,但是线程安全的例子,帮助大家理解
funca()
{
lock(a);
......//interrupt by signal and call funca(), so dead lock
unlock(a);
}
int main()
{
signal(sig, funca);
funca();
}
kakaying
2007-05-31
打赏
举报
回复
学习
_17708668
2007-05-31
打赏
举报
回复
Chiyer(星羽) 兄给出了全局变量的线程安全处理示例:这种情况说明的是多个线程实例并发操作同一存储区域的数据的问题,就应用角度来说,本身就是不可重入的。
可重入的定义请翻阅相关课本。
微软早期的OS中的多线程是不可重入的,比如下面这个线程函数并发 3 次
void fun(void*p)
{
int i = 0;
++i;
}
最后得到的结果可能是 1,2,3 中任何结果。可能当时微软的多线程函数中的局部变量不是采用的堆栈,而是采用的共享存储。当时要做到线程函数中的局部变量相互独立(即保证线程安全,也可以说保证线程函数可重入----但可重入表现在计算科学各方面,不只是线程),Borland 提供了 C++ 多线程库。
feimingbiao
2007-05-31
打赏
举报
回复
这两个不是一个意思。但有时候有重叠。在多线程情况下,县城安全是可重入的必要条件。但是线程安全不一定能保证可重入。
比如单线程程序的函数,当然不存在线程安全问题,但不一定就是可重入的。比较经典的例子是最早DOS的TSR程序,由于用了同一堆栈指针,函数重入的时候会把栈写坏。还有比如Fortran一类的不支持递归的语言,由于变量是静态地址,无法可重入。
总之对于可重入函数,里面不能有大家同时可以用的公共资源。比如下面程序:
int 阶乘(int n)
{
static int i = 1;
if (n)
i = i * 阶乘(n-1);
else
i = 0;
return i;
}
即使单线程也会出问题。
ming4098
2007-05-31
打赏
举报
回复
学习
星羽
2007-05-30
打赏
举报
回复
帮 fengdream(Be an early vegetable bird~~~) ( )
这个这个文章贴出来方便看
一个函数被称作“线程安全”的,当且仅当它被多个线程反复调用时,它会一直产生令人期待的正确的结果。反之为“线程不安全”函数,它主要有两种类型:
(1)不保护共享变量的函数,包括全局变量和本地静态变量(static)。
我们可以使用POSIX信号量加以解决:
Sem_t mutex;
Sem_init(&mutex,0,1);
Sem_wait(&mutex);
……
……
Sem_post(&mutex);
优点:简单易行;
缺点:同步操作p、v将影响程序的执行时间。
(2)返回指向静态变量的指针的函数,如gethostbyname,gethostbyaddr,inet_ntoa等等。
我一般这样使用gethodtbyname:
Struct hostent *hostp;
Hostp=gethostbyname(scorpion.cublog.cn);
……
……
Gethostbyname将执行结果存放在自己的static struct hostent变量中,并返回一个指向这个结构的指针。如果我们从并发线程中调用这个函数,那么将发生不可预料的结果,正在被一个线程使用的结果,可能悄悄地被其它线程覆盖。
解决办法:(a)、改写库函数gethostbyname,增加一个参数,将本地结构变量传入gethostbyname,
如:
Struct hostent host;
Gethostbyname(&host,scorpion.cublog.cn);
再使用host方可!
(b)、改写库函数gethostbyname,不是返回指针,而是直接返回struct hostent.
缺点:struct hostent结构较大,影响函数的效率。
以上两种办法(a)、(b),要求修改库函数,基本上不可行!
(c)、使用lock –and-copy技术,即定义自己的封装函数,通过调用它来取代直接使用gethostbyname.
struct hostent *gethostbyname_my(char *hostname)
{
struct hostent *shar,*unshar;
unshar=malloc(sizeof(struct hostent))
sem_wait(&mutex);
shar=gethosybyname(hostname);
*unshar=*shar;
srm_post(&mutex);
return unshar;
}
现在大多数unix\linux操作系统,提供了线程不安全函数的可重入版本,如:gethostbyname_r。但是不同的系统可能接口不一样,所以建议不使用它们!还是使用我们自己的封装函数。
可重入函数,是线程安全函数的一种。特点:当它们被多个线程调用时,不会引用任何共享数据,也就是不引用静态或全局变量。如,gethostbyname_my是线程安全函数,而不是可重入函数。
星羽
2007-05-30
打赏
举报
回复
补考过了,还拿优 = =!
星羽
2007-05-30
打赏
举报
回复
怪不得,我想了半天都不知道 信号安全 跟 可重入 有什么关系 = =!
哈哈,信号安全 大学一门课,我挂了 = =!
jixingzhong
2007-05-30
打赏
举报
回复
http://www.ibm.com/developerworks/cn/linux/l-reent.html
【确保可重入性的经验】 部分的内容不错,
可以一看。
一些经验之谈,
可以提供有些帮助 ...
jixingzhong
2007-05-30
打赏
举报
回复
可以认为 可重入 是保证 线程安全 的一种方式 ...
jixingzhong
2007-05-30
打赏
举报
回复
基本上可以认为,如果代码是可重入的(reentrant),或者通过某种形式的互斥而实现对并发访问的保护,则代码是线程安全的。
Oversense
2007-05-30
打赏
举报
回复
线程安全 和 可重入 其实是2个东西,
不过一般情况下可以认为 可重入函数都是 线程安全的
也有其他 情况,这个要看定义了,比如
void foo(int *i)
{
int b = *i;
b++;
*i = b;
};
这个函数不是线程安全的,但是可重入
如果一个函数使用线程本地存储,互斥体等,也可以实现线程安全,但是可以不是 可重入的
fengdream
2007-05-30
打赏
举报
回复
可重入函数,是线程安全函数的一种。特点:当它们被多个线程调用时,不会引用任何共享数据,也就是不引用静态或全局变量。
请参考下面这篇文章:
http://blog.chinaunix.net/u/15929/showart.php?id=116221
netxuning
2007-05-30
打赏
举报
回复
学习
goodluckyxl
2007-05-30
打赏
举报
回复
我觉得 可重入是针对多线程中调用同一函数处理的防止异步共享导致数据不安全
它是线程安全一个可靠保证
它和线程安全应该属于一种必要关系
也就是保证纤尘安全必须保证多线程的调用函数均为可重入
而仅仅满足可重入不能满足线程安全
线程安全建立在很多安全基础之上, 需要使用信号,原子操作防止发生数据不一致导致不安全
dai_weitao
2007-05-30
打赏
举报
回复
我认为线程安全是由可重入和互斥两部分组成。
VCLIFE
2007-05-30
打赏
举报
回复
study
asert
2007-05-30
打赏
举报
回复
可重入函数,是线程安全函数的一种
-------------------------------
那还有哪几种,说来听听
asert
2007-05-30
打赏
举报
回复
mark
.net 必知
.NET牛人应该知道些什么? A、任何
一个
使用.NET的人 1、描述线程与进程的区别? 2、什么是Windows服务,它的生命周期与标准的EXE程序有什么不同 ? 3、Windows上的单个进程所能访问的最大内存量是多少?它与系统的最大虚拟内存一样吗?这对于系统设计有什么影响? 4、EXE和DLL之间的区别是什么? 5、什么是强类型,什么是弱类型?哪种...
.NET牛人测试题目
.NET牛人应该知道些什么? A、任何
一个
使用.NET的人 1、描述线程与进程的区别? 2、什么是Windows服务,它的生命周期与标准的EXE程序有什么不同 ? 3、Windows上的单个进程所能访问的最大内存量是多少?它与系统的最大虚拟内存一样吗?这对于系统设计有什么影响? 4、EXE和DLL之间的区别是什么? 5、什么是强类型,什么是弱类型?哪种更好些?为
基础知识,面试题,牛人
任何
一个
使用.NET的人8, 中级.NET开发人员 20, C# 组件开发人员10, 高级开发人员架构师 25, ASP.NET(UI)开发人员21, XML开发人员16 一、任何
一个
使用.NET的人 8 1.描述线程与进程的区别? 程 序与进程
概念
是不可分的。程序是为了完成某项任务编排的语句序列,它告诉计算机如何执行,因此程序是需要运行的。程序运行过程中需要占有计算机的各种资源 才能运行下去。如...
Solidity 安全:已知攻击方法和常见防御模式综合列表
虽然处于起步阶段,但是 Solidity 已被广泛采用,并被用于编译我们今天看到的许多以太坊智能合约中的字节码。相应地,开发者和用户也获得许多严酷的教训,例如发现语言和EVM的细微差别。这篇文章旨在作为
一个
相对深入和最新的介绍性文章,详述 Solidity 开发人员曾经踩过的坑,避免后续开发者重蹈覆辙。
重入
漏洞 以太坊智能合约的特点之一是能够调用和利用其他外部合约的代码。合约通常也...
RealPython 中文系列教程(三十四)
立即观看**本教程有真实 Python 团队创建的相关视频课程。Python 中的线程Python 线程化允许您同时运行程序的不同部分,并且可以简化您的设计。如果你有一些 Python 的经验,并且想用线程加速你的程序,那么这个教程就是为你准备的!什么是线程如何创建线程并等待它们完成如何使用如何避免竞态条件如何使用 Pythonthreading提供的常用工具本文假设您已经很好地掌握了 Python 基础知识,并且正在使用至少 3.6 版本来运行这些示例。如果你需要复习,你可以从。
C语言
70,024
社区成员
243,263
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章