C 语言可重入函数

2024 年 8 月 28 日 | 3 分钟阅读

在本文中,我们将讨论 C 语言中的可重入函数,并介绍其特性和示例。

如果一个函数在执行过程中可以被中断,然后去处理中断服务程序,之后再重新开始执行先前被中断的函数而不会造成任何损害,那么这样的函数就称为可重入函数。可重入函数被用于多种应用场景,如处理硬件中断、递归等。

可重入函数的特性

在 C 语言中,可重入函数有几个特性。可重入函数的一些主要特性如下:

  1. 它不使用全局静态数据。尽管没有严格的限制,但通常不建议这样做。这是因为用新数据重新启动可重入函数可能会产生意想不到的后果,并且中断可能会改变某些全局设置。
  2. 它不应修改自己的源代码。这一点至关重要,因为函数在整个代码中的行为应该是一致的。但如果中断程序每次使用不同的值或在中断前后都使用可重入函数的本地副本,则是可以接受的。
  3. 可重入函数不能调用任何其他非可重入的函数或需要同步的例程。

可重入函数的示例

在这里,我们将讨论 C 语言中可重入函数的几个示例并加以解释。

示例:1

strtok()

strtok() 方法可以根据分隔符将一个字符串标记化(分割)为更小的字符串。它不是线程安全的,因为它使用一个静态指针来保存其内部状态。可以使用可重入版本strtok_r()使其可重入,或者可以在外部管理状态(例如,为每个线程使用不同的数据结构),或两者兼而有之。

代码

输出

Token: Hello
Token: world
Token: this
Token: is
Token: a
Token: test

示例:2

qsort()

qsort() 函数使用快速排序算法对数组进行排序。元素的顺序只能通过一个比较函数来确定。由于其共享的工作空间,qsort()默认情况下不是可重入的,但可以通过提供一个自定义的比较函数和一个包含排序所需额外数据的上下文来使其可重入。

代码

输出

1 2 5 6 8

例如:3

rand()

rand()函数生成一个伪随机整数。尽管它默认不是线程安全的(由于共享的内部数据),但可以通过使用可重入版本的rand_r()使其可重入,该版本接受一个指向无符号整数的指针作为种子。

代码

输出

Random Number: 212005489
Random Number: 2042157013
Random Number: 2068794670
Random Number: 1367026107
Random Number: 927415125

请注意:- 每次运行代码时,这些数字都会不同。

结论

总之,C 语言中的可重入函数对于多线程程序的高效和安全执行至关重要。这些函数允许多个线程同时调用同一个函数,而不会发生意外的干扰或数据损坏。通过维护独立的本地数据和避免使用共享资源,可重入函数在降低同步复杂性的同时,提供了高效的并行处理能力。