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

1. Signal信号简介

       信号是软件层次上模拟的中断,它是一种异步通讯的处理机制。信号的异步性意味着,应用程序不用等待事件的发生,当信号发生时应用程序自动陷入到对应的信号处理函数中。产生信号的事件对进程而言是随机出现的。信号的响应方式有忽略、捕捉、执行默认动做三种。安全

2. 线程安全

       线程安全函数:在C语言中局部变量是在栈中分配的,任何未使用静态数据或其余共享资源的函数都是线程安全的。使用全局变量的函数是非线程安全的。使用静态数据或其余共享资源的函数,必须经过加锁的方式来使函数实现线程安全。并发

       线程安全的(Thread-Safe):若是一个函数在同一时刻能够被多个线程安全地调用,就称该函数是线程安全的。线程安全函数解决多个线程调用函数时访问共享资源的冲突问题。异步

3. 可重入

       可重入(Reentrant)函数能够由多于一个线程并发使用,而没必要担忧数据错误。可重入函数能够在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入性解决函数运行结果的肯定性和可重复性。函数

1)        一个函数对于多个线程是可重入的,则这个函数是线程安全的;spa

2)        一个函数是线程安全的,但并不必定是可重入的,好比使用互斥锁实现的线程安全;线程

3)        可重入性要强于线程安全性。递归

4. Signal信号处理

       信号处理函数中只能调用可重入函数,而不能调用不可重入函数。进程捕捉到信号并对其进行处理时,正在执行的正常指令序列就被信号处理程序临时中断,它首先执行该信号处理函数中的指令。若是从信号处理程序返回,则继续执行在捕捉到信号时正在执行的正常指令序列(这相似于发生硬件中断时所作的)。但在信号处理函数中,不能判断捕捉到信号时线程执行到何处。进程

       信号处理函数默认状况下是在进程的主线程调用的,这种状况下使用不可重入函数,有可能会形成不可预知的错误。好比调用了malloc函数,为了保证malloc是线程安全的,因此内部使用了锁,根据malloc中锁的不一样处理方式,分别可能会致使如下状况的发生:事件

1)        若是是普通锁,在主线程中malloc函数获取锁以后被signal中断,在signal处理函数中继续调用malloc,由于主线程中的malloc已经获取到了锁,signal处理函数只能等待锁释放,而主线程中的malloc函数正在等待signal处理函数返回后继续执行,这样就形成了锁死;内存

2)        若是是递归锁,那么signal处理函数中的malloc函数获取锁后进行内存分配,由于上次的malloc操做还没完,可能成会形成内存数据混乱。

       就定时而言,可不直接使用singal alarm,而使用posix定时器,经过通知线程的方式,将定时处理函数放到单独的线程中来处理。

相关文章
相关标签/搜索