线程安全与重入以及异步信号安全的区别.

可重入一定是线程安全的,但是线程安全不一定是可重入的.

http://www.cnblogs.com/baizx/p/5128862.html

 线程安全:
       
线程安全函数:在C语言中局部变量是在栈中分配的,任何未使用静态数据或其他共享资源的函数都是线程安全的。
                     
使用全局变量的函数是非线程安全的。
                     
使用静态数据或其他共享资源的函数,必须通过加锁的方式来使函数实现线程安全。

       线程安全的(Thread-Safe)
                   
如果一个函数在同一时刻可以被多个线程安全地调用,就称该函数是线程安全的。
                   
线程安全函数解决多个线程调用函数时访问共享资源的冲突问题。

       可重入(Reentrant)
                   
函数可以由多于一个线程并发使用,而不必担心数据错误。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重  入性解决函数运行结果的确定性和可重复性。


可重入函数编写规范为:

1、不在函数内部使用静态或全局数据 
2
、不返回静态或全局数据,所有数据都由函数的调用者提供。 
3
、使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
4
、如果必须访问全局变量,利用互斥机制来保护全局变量。
5
、不调用不可重入函数。

两者之间的关系:
1
、一个函数对于多个线程是可重入的,则这个函数是线程安全的。
2
、一个函数是线程安全的,但并不一定是可重入的。【使用互斥锁实现的线程安全】
3
、可重入性要强于线程安全性。

具体看代码,这里的thread_safe_not_reentrant就是一个例子,请忽略printf调试函数,我没有查这个函数的重入特性。

请在运行以后按下ctrl c,观察程序死锁。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>        /* for convenience */
#include <stdlib.h>       /* for convenience */
#include <unistd.h>       /* for convenience */
#include <signal.h>       /* for SIG_ERR */
#include <pthread.h>
 
pthread_mutex_t env_mutex;
void  thread_safe_not_reentrant( char  *name){
     printf ( "call from %s\n" ,name);
     pthread_mutex_lock(&env_mutex);
     sleep(5);
     pthread_mutex_unlock(&env_mutex);
     printf ( "return from %s\n" ,name);
}
static  void
sig_int( int  signo)
{
     printf ( "caught SIGINT\n" );
     thread_safe_not_reentrant( "sig int " );
}
 
 
 
int
main( void )
{
     //if default mutex ,it use recursive , will not deadlock
     //env_mutex=PTHREAD_MUTEX_INITIALIZER;
     pthread_mutexattr_t attr;
     pthread_mutexattr_init(&attr);
     pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL);
     pthread_mutex_init(&env_mutex,&attr);
     pthread_mutexattr_destroy(&attr);
     if  ( signal (SIGINT, sig_int) == SIG_ERR)
         printf ( "signal(SIGINT) error" );
     thread_safe_not_reentrant( "main" );
     return  0;
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值