多线程-可重入函数要满足哪些特征?

发布于 2017-01-06 22:34:46 字数 0 浏览 1415 评论 3

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清晨说ぺ晚安 2017-08-05 16:26:56

1)什么是可重入性?
  可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反, 不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在代码的关键部分禁用中断)。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入函数要么使用本地变量,要么在使用全局变量时保护自己的数据。
  2)可重入函数:
  不为连续的调用持有静态数据。
  不返回指向静态数据的指针;所有数据都由函数的调用者提供。
  使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
  如果必须访问全局变量,记住利用互斥信号量来保护全局变量。
  绝不调用任何不可重入函数。
  3)不可重入函数:
  函数中使用了静态变量,无论是全局静态变量还是局部静态变量。
  函数返回静态变量。
  函数中调用了不可重入函数。
  函数体内使用了静态的数据结构;
  函数体内调用了malloc()或者free()函数;
  函数体内调用了其他标准I/O函数。
  函数是singleton中的成员函数而且使用了不使用线程独立存储的成员变量 。
  总的来说,如果一个函数在重入条件下使用了未受保护的共享的资源,那么它是不可重入的。
  4)示例
  在多线程条件下,函数应当是线程安全的,进一步,更强的条件是可重入的。可重入函数保证了在多线程条件下,函数的状态不会出现错误。以下分别是一个不可重入和可重入函数的示例:

//c code
  static int tmp;

  void func1(int* x, int* y)
{
  tmp=*x;
  *x=*y;
  *y=tmp;
  }

  void func2(int* x, int* y)
{
  int tmp;
  tmp=*x;
  *x=*y;
  *y=tmp;
  }

func1是不可重入的,func2是可重入的。因为在多线程条件下,操作系统会在func1还没有执行完的情况下,切换到另一个线程中,那个线程可能再次调用func1,这样状态就错了。
两者之间的关系:
1、一个函数对于多个线程是可重入的,则这个函数是线程安全的。
2、一个函数是线程安全的,但并不一定是可重入的。
3、可重入性要强于线程安全性。
比如:strtok函数是既不可重入的,也不是线程安全的。加锁的strtok不是可重入的,但线程安全。而strtok_r既是可重入的,也是线程安全的。(具体可以查看man手册)

可重入函数,是线程安全函数的一种。特点:当它们被多个线程调用时,不会引用任何共享数据,也就是不引用静态或全局变量。

泛泛之交 2017-07-26 23:55:53

在信号处理函数中,也要考虑函数可重入的情况。
考虑到这样一种情况:如果进程正在执行malloc,在堆中分配了另外的存储空间,而此时由于捕捉到信号而执行信号处理程序,其中又调用了malloc,这时候可能会造成破坏,因为malloc通常为它分配的存储区维护一个链接表,而插入执行信号处理程序时,进程可能正在更改此链表。

函数不可重入,大多是因为:(1)使用了静态数据结构,(2)它们调用malloc()或free,(3)它们是标准I/O函数。标准I/O库的很多实现都以不可重入的方式使用全局数据结构(如errno变量)。

下图是信号处理中可以调用的重入函数。(来自<<UNIX环境高级编程>>)

虐人心 2017-04-06 05:15:37

至少要满足下面几条:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文