可重入函数

可重入函数

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

Signal处理中的函数可重入问题

偶尔善良 提交于 2019-12-07 07:44:05
1. Signal信号简介 信号是软件层次上模拟的中断,它是一种异步通信的处理机制。信号的异步性意味着,应用程序不用等待事件的发生,当信号发生时应用程序自动陷入到对应的信号处理函数中。产生信号的事件对进程而言是随机出现的。信号的响应方式有忽略、捕捉、执行默认动作三种。 2. 线程安全 线程安全函数:在C语言中局部变量是在栈中分配的,任何未使用静态数据或其他共享资源的函数都是线程安全的。使用全局变量的函数是非线程安全的。使用静态数据或其他共享资源的函数,必须通过加锁的方式来使函数实现线程安全。 线程安全的(Thread-Safe):如果一个函数在同一时刻可以被多个线程安全地调用,就称该函数是线程安全的。线程安全函数解决多个线程调用函数时访问共享资源的冲突问题。 3. 可重入 可重入(Reentrant)函数可以由多于一个线程并发使用,而不必担心数据错误。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入性解决函数运行结果的确定性和可重复性。 1) 一个函数对于多个线程是可重入的,则这个函数是线程安全的; 2) 一个函数是线程安全的,但并不一定是可重入的,比如使用互斥锁实现的线程安全; 3) 可重入性要强于线程安全性。 4. Signal信号处理 信号处理函数中只能调用可重入函数,而不能调用不可重入函数。进程捕捉到信号并对其进行处理时

重读APUE(11)-信号安全的可重入函数

走远了吗. 提交于 2019-12-02 22:08:01
重入时间点 进程捕捉到信号并对其进行处理时,进程正在执行的正常指令序列就会被信号处理程序临时中断,它首先执行该信号粗合理程序中的指令;如果从信号处理程序返回,则继续执行捕捉到信号时进程正在执行的正常指令序列; ps:如果了解驱动,上面这段信号打断流程与中断打断进程上下文很类似; 不可重入函数 对于有些函数,是不可重入的,如果信号处理程序打断了这些函数的执行,同时信号粗合理程序中也调用这个函数,就会发生错误;这些不可重入的函数,有如下特点: 1. 使用了静态的数据结构; 2. 调用了malloc或者free; 3. 是标准的I/O函数;标准IO库的很多实现都以不可重入方式使用全局数据结构; 我们自己写程序时,应该尽量的注意将函数实现为可重入,如果不可重入,则需要进行锁保护; 信号安全的函数 下面的列表为异步信号安全的函数,除了可重入以外,在信号处理操作期间,它会阻塞任何引起不一致信号的发送;也就是说信号处理程序可以安全的调用这些函数; errno 即使使用了信号安全的函数,但是由于每个线程只有一个errno,所以信号处理程序可能会修改它原来的值;作为一个通用规则,在信号处理程序中调用上图中的函数时,应当在调用前堡村errno,在调用后恢复errno;(经常被捕获到的信号是SIGCHLD,其信号处理程序通常要调用一种wait函数,而各种wait函数多能改变errno)

Linux-可重入函数(day10)

匿名 (未验证) 提交于 2019-12-02 21:56:30
Ŀ¼ 一、信号阻塞与信号未决 二、pause(2)的使用 三、信号传送过程处理 四、可重入函数 五、编写代码实现信号处理函数的继承 六、setitimer实现定时器 四、可重入函数   信号处理函数,尽量保证为可重入函数。 #include<stdio.h> #include<signal.h> #include<unistd.h> void doit(int n){ int v; static int c=0; v=c; v++; usleep(5000); c=v; printf("c=%d\n",c); return; } int main(void){ signal(2,doit); while(1){ doit(2); } return 0; }