首页 > 编程语言 >C++ 线程安全和可重入函数

C++ 线程安全和可重入函数

时间:2023-05-23 18:45:26浏览次数:37  
标签:重入 加锁 函数 C++ 安全 线程 执行

线程安全

线程安全是指在多线程环境下,同一函数或函数库被不同线程调用,不会出现数据不一致的情况。

如何确保一个函数是线程安全的:

1.对共享资源加锁。

2.从逻辑上进行设计,保证资源的访问修改不会冲突。

一般情况下我们使用加锁的方式保证线程安全,具体加锁操作有互斥锁、条件变量、信号量以及读写锁。

 

可重入函数
若一个程序或子程序(或函数)可以“在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错”,则称其为可重入(reentrant)的。即当该子程序正在被执行是,执行线程可以再次进入并执行它,仍然获取符合预期的结果。

上面提到的线程安全是多线程并发执行时,而可重入强调对单个线程执行时重新进入同一个子程序仍然是安全的。

若一个函数式可重入的,应满足下述条件:

不能含有静态或全局非常量数据。
不能返回静态或全局非常量数据的地址
不能调用标准 I/O
调用的函数也必须是可重入的
没有动态分配或释放堆资源
即保证可重入函数使用的所有变量都保存在调用栈的当前栈帧中,保证执行该函数时使用的栈帧不重入、不相互覆盖,从而保证可重入执行安全。

线程安全与可重入函数的对比
可重入函数未必是线程安全的;线程安全函数未必是可重入的。

例如,一个函数打开某个文件并读入数据。这个函数是可重入的,因为它的多个实例同时执行不会造成冲突;但它不是线程安全的,因为在它读入文件时可能有别的线程正在修改该文件,为了线程安全必须对文件加“同步锁”。
另一个例子,函数在它的函数体内部访问共享资源使用了加锁、解锁操作,所以它是线程安全的,但是却不可重入。因为若该函数一个实例运行到已经执行加锁但未执行解锁时被停下来,系统又启动该函数的另外一个实例,则新的实例在加锁处将转入等待。如果该函数是一个中断处理服务,在中断处理时又发生新的中断将导致资源死锁。fprintf函数就是线程安全但不可重入。

判断一个函数是不是可重入函数,关键在与,是否能能够在被中断后,处理完中断后恢复运行得到正确的结果。在Linux中可以指执行完信号处理函数结果正确。

如果函数对异步信号处理程序的重入是安全的,那么就可以说函数是”异步-信号安全”的。

可重入函数与是否使用锁无关,而线程安全大多需要锁机制来保证线程安全。

如果程序在获得锁之后被中断,转去执行信号处理函数,而恰好该信号处理函数也调用了该函数,此时锁已经被占用,线程处理函数无法获得锁,可能导致死锁。

 

原文链接:https://blog.csdn.net/a1414345/article/details/71794597

标签:重入,加锁,函数,C++,安全,线程,执行
From: https://www.cnblogs.com/linxisuo/p/14472673.html

相关文章

  • C++
    实现一个类模板,它可以接受一组数据,能对数据排序,也能输出数组的内容。每行输入的第一个数字为0,1,2或3:为0时表示输入结束;为1时表示将输入整数,为2时表示将输入有一位小数的浮点数,为3时表示输入字符。如果第一个数字非0,则接下来将输入一个正整数,表示即将输入的数据的数量。templat......
  • 多线程下载图片并压缩
    从ftp服务器下载文件,文件里是多张图片的name和uri,格式是name||uri,根据uri下载图片并压缩存储到本地服务器主要流程:1 从ftp服务器下载文件,2 将文件格式解析后的地址存入map容器内,3 计算每个线程需要下载的url,并循环调用threadPool.execute(mythead),子线程根据uri下......
  • c++打卡第三十五天
    一、最大公约数1、问题描述 2、设计思路本题中可以有三种算法,其中我们提供第三种辗转相除法的代码,第一种是从1开始,由于最大公约数可以是最小的那个数,所以我们循环条件到两个之中的小数,如果这个数满足可以整除两个整数,遍历到最大的那个数时,打印出来。第二种是从小数开始循环,当......
  • C++ 模板 使用 enum 代替 typename
    enumtestEnum{A,B,C};template<testEnumC>classTestClassTemplate{public:voidprint(){printf("common\n");}};template<>classTestClassTemplate<A>{public:voidprint(){printf(&quo......
  • SQLite3 客户端程序,Win32 SDK ,C/C++
    1 WIn32SDK程序,尽量放在一个文件中,主要用到Tree,ListView,Edit控件。2 把控件封装成类,但不封装窗口回调函数。类实例为全局变量,方便消息回调函数调用执行。这样做最简单。3 Edit控件处理按键输入,模仿shell执行SQL查询4打开数据库文件时若没有此文件则新建,否则打开,打开......
  • c++的前世今生
    C++语言是本贾尼·斯特劳斯特卢普在1982年发明的,早期版本被称为CwithClasses,之后在1983年更名为C++。C++语言在发明后很快就获得了广泛的应用,由于其具有高效、灵活和兼容性强的特点,成为了许多领域的首选编程语言。在计算机科学和工程领域,C++语言被广泛用于开发操作系统、......
  • 多线程要点博客锦集
    写的好的博客要收藏起来,避免以后丢失!1、Java多线程:彻底搞懂线程池2、Java线程池实现原理及其在美团业务中的实践......
  • 【重学C++】04 | 说透C++右值引用(上)
    文章首发【重学C++】04|说透C++右值引用、移动语义、完美转发(上)引言大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第四讲,在前面《03|手撸C++智能指针实战教程》中,我们或多或少接触了右值引用和移动的一些用法。右值引用是C++11标准中一个很重要的特性。第一次接......
  • Python多线程爬虫又来了
    Python多线程的主要好处是可以在单个程序中同时执行多个任务,从而提高应用程序的性能和效率。具体来说,多线程有以下几个优点:提高CPU利用率:通过多线程,可以更充分地利用CPU资源,尤其适用于计算密集型的任务。降低IO阻塞:对于需要等待IO操作完成的任务(如网络请求或文件读写),将它们放入......
  • linux创建线程报错资源受限
    LinuxError:11Resoucetemporarilyunavailable可能涉及到的限制:1、/proc/sys/kernel/threads-max系统允许的最大线程数2、/proc/sys/kernel/pid_max系统最大pid值3、用户资源限制ulimit-u查看当前用户的maxuserprocesses......