线程安全和函数可重入

C/C++



线程安全和函数可重入

可重入和线程安全, 这2个是完全不同的概念;

可重入函数只有在signal下会发生, 比如一个函数在执行时被中断, 在中断处理函数中又一次被调用, 这2次(每次)调用都能产生正确的结果,那就个可重入函数;

可重入函数

看一个不可重入的例子:

void  sig_handler(int sig)
{
    ...
    gethostbyname("www.baidu.com");
    ....
    alarm(1);
}
int main()
{
    signal(SIGALRM,sig_handler);
    alarm(1);
    while(1){
        ....
        gethostbyname("www.google.com");
        printf(...);
    }
 
    return 0;
}

gethostbyname 内部实现有一个静态局部变量, 或一个静态全局变量;

这意味着, 在main中gethostbyname的调用刚执行完或者只执行了一半, 此时signal来了, 转到sig_handler继续调用gethostbyname ,由于实现是一个静态变量,因此后调用gethostbyname将把前一次的数据覆盖.

因此可以想象, 如果一个函数内部使用了静态/全局变量来做数据处理或者返回此静态/全局变量,那么一定是一个不可重入函数;

线程安全

简单来说就是加锁操作;
那么线程安全的函数就一定是可重入的吗 ? 答案是否定的

例如:

malloc 是线程安全的,他将操作一个全局链表 , 一旦在执行过程中被sigal中断,直接完蛋

pthread_mutex_lock 他是线程安全吧, 一旦执行过程中被中断, 中断处理中又一次pthread_mutex_lock可能直接死锁或者破坏了内部状态

在比如:,线程安全? 能在中断之后正确的执行吗?

int func(){
    static int i = 0;
    lock ;
    ++i;
    unlock ;
    return i;
}

总之线程安全跟可重入是2个概念 , 虽然他们之间有些交集;

一个函数中如果使用了静态/全局变量, 那他基本是一个不可重入的函数,当然具体还是看实现;如果此函数中加了

锁,那么他是线程安全的, 如果内部也把静态/全局变量都删了, 也不额外调用不可重入函数的话,那他就是一个

即线程安全也可重入的函数了 .

最后 , 一个可重入的函数 是一个线程安全的函数 ?

不一定 ; 只不过一般情况可重入的函数是线程安全的,

原因:

你自己想嘛 , 不可重入函数的特点就是 [ 使用或返回了静态/全局变量 或 使用了额外的不可重入函数 ]

那么可重入函数必然不调用或不使用那些玩意,

猜你喜欢

转载自blog.csdn.net/zyq880625/article/details/132040595