社区
C语言
帖子详情
"线程安全" 和 "可重入" 是一个概念吗?(更正帖子)
see22
2007-05-30 10:33:13
对不起,刚才发错了一个帖子,将“线程安全”写成“信号安全”了,
现在更正:
"线程安全" 和 "可重入" 是一个概念吗? 如果不是,区别在哪里?
...全文
1631
20
打赏
收藏
"线程安全" 和 "可重入" 是一个概念吗?(更正帖子)
对不起,刚才发错了一个帖子,将“线程安全”写成“信号安全”了, 现在更正: "线程安全" 和 "可重入" 是一个概念吗? 如果不是,区别在哪里?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用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
知识点:Java sychronized 内部锁实现原理
本文围绕Java并发编程中synchronized关键字展开,介绍了其用法、内部锁机制及可
重入
性。分析了synchronized锁的实现,包括字节码层面和ObjectMonitor内部结构与逻辑,还阐述了锁的状态及升级逻辑。此外,讲解了JDK对synchronized锁的优化,如锁消除、锁粗化和自旋锁等。
Java多线程学习笔记(上)
本文详细介绍了Java中的进程与线程
概念
,包括线程的状态、创建方式以及线程间的同步与通信。讨论了线程上下文切换、
线程安全
的实现,如`synchronized`关键字、`ReentrantLock`和并发工具类的使用。还涉及了死锁、活锁、饥饿等问题的预防和解决策略,提供了丰富的示例代码和实践建议。
梁昱森 高级软件工程 学习总结
本文分享了作者通过《软件工程(C编码实践篇)》课程学习的心得体会,包括对软件工程的理解、线上实验中学到的知识点如代码规范、内部模块化、可重用等,以及线下学习的内容如代码版本控制、软件生命周期等。
tomcat线程被打满怎么排查_字节跳动后端Java面试题——MySQL、Tomcat、设计模式、并发编程...
本文涵盖MySQL、Tomcat、设计模式及并发编程等Java核心技术领域的面试要点。深入解析数据库三范式、索引机制、Tomcat优化策略、设计模式应用及并发编程实践等内容。
实用代码脚本易语言源码易用课件大师
实用代码脚本易语言源码易用课件大师
C语言
70,038
社区成员
243,247
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章