看UNIX编程相关的书在讲信号的时候会列出一大堆的保证信号安全的函数,在讲线程的时候也会例出一些不保证线程安全的函数。需要把它们都记下来吗?我觉得太可不必,也不科学,不了解根本你很可能自己写出一个不安全的函数,然后在信号处理里或是多线程程序里使用,出了问题却莫名其妙!
一般来说如果函数内部使用了静态变量或是全局变量,或是传了引用进去的函数就不具可重入性。具体可重入函数的概念可以去百度一下。
在带信号处理的程序里,因为信号处理的异步性,所以很可能当你正在调用函数A的时候被信号打断了,当你在该信号时处理函数里又调用了函数A,这进你就重复调用了函数A,这时就你要考虑函数A是不是可重入函数。所以一个函数是否信号安全基本就跟该函数是否可重入相等。
在多线程程序里也一样,因为子线程随时可能在某个函数里被中断,然后去运行另一个线程,如果另一个线程里也恰好调用了这个函数,这样是否线程安全也同样被提出来了。
从上是否就可以得出信号安全跟线程安全就是相等了呢?事实是不一样的,要不然那些教材也不会分别把信号安全跟线程安全的函数列出来,举个简单的例子,malloc不是信号安全的,但却是线程安全的,这内部的区别在哪呢?百度一下,原来,malloc函数的内部使用了锁的机制,所以,当你如果程序里调用了malloc前在调度这个函数时被信号中断了再在信号处理函数里调用malloc的话,就有可能出现死锁。而此种情况在多线程程序里却不存在,因为第二个线程会挂起,继续运行线程1直接线程1完成malloc释放锁。 所以信号安全跟线程安全基本相同,但考虑到信号处理函数必须返回后程序才能继续,信号安全跟线程安全又稍有不同。