线程安全与可重入函数

线程安全

一个函数称为线程安全的,当且仅当被多个并发线程反复调用时,它会一直产生正确的结果。
线程安全问题主要是由全局变量和静态变量引起的。
如果每个线程对全局变量,静态变量只有读操作,没有写操作。一般来说这个全局变量是线程安全的。当多个线程同时执行写操作,要保证线程安全,一般就要保证线程的同步问题。
因为全局变量引起的线程安全


#include<stdio.h>
#include<pthread.h>
int num=0;
void* fun()
{
    int i=0;
    while(i<1000)
    {
        int temp=num;
        printf("thread is:%u,g_val:%d\n",pthread_self(),num);
        num=temp+1;
        i++;
    }
}
int main()
{
    pthread_t id1,id2;
    pthread_create(&id1,NULL,fun,NULL);
    pthread_create(&id2,NULL,fun,NULL);
    pthread_join(id1,NULL);
    pthread_join(id2,NULL);
    printf("%d\n",num);
    return 0;


}

这里写图片描述
这里的结果并不是1000,而且多次运行结果也不一样。两个线程对于一个全局变量的操作不是原子的,两个线程操作同一块代码顺序是不可预期的。

可重入函数

可重入函数是线程安全的一类。函数被不同的控制流程调用时,有可能在第一次调用时还没返回时就再次进入该函数,称为重入。
一个程序main函数调用insert函数向一个链表中插入一个节点,插入需要两步,新节点temp,当前节点cur,temp->next=cur和head=temp两步操作。当只进行了第一步时,因为硬件中断使得进程切换到内核态,再次回到用户态时检测到有信号要处理,于是执行了这个信号,也是调用insert函数插入节点,插入成功后返回到内核态,再次返回到用户态就继续往下执行,刚开始做了一步的插入操作就被打断。最后插入了两个节点,却只有一个节点真正的插入进去了。像这种函数称为不可重入函数,insert访问的是一个全局链表,因为重入而错乱。反之,一个函数之访问自己的局部变量或参数,称为可重入函数

两者比较

1.线程安全是在多线程的情况下引发的,可重入函数时一个线程
2.线程安全不一定是可重入的,但可重入一定是线程安全的
3.如果一个函数由全局变量,这个函数的线程不是线程安全也不是可重入的。
4.如果一个函数当中的数据有自身的栈空间,则这个函数是线程安全且是可重入函数。
5.如果对临界资源的访问加锁,则这个函数是线程安全的。但如果这个重入函数锁未释放就会产生死锁,则是不可重入的。
6.线程安全能够使不同的线程访问同一块地址空间,可重入要求不同的执行流对数据的操作互不影响的结果相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值