在下面这篇博文中,已经了解了线程安全的基本概念了,
http://blog.csdn.net/boyxulin1986/article/details/19345603
下面这个函数是非线程安全的。
在多线程环境中,如果有多个线程同时对同一全局数据进行写操作,
则会导致写操作出错。
example1:
int set_flag(int flag)
{
g_flag = flag;
return g_flag;
}
这时可以使用信号量等手段进行保护。
这样多个线程如果同时进行写访问,就需要根据拿到mutex的顺序来先后执行。
example2:
int set_flag(int flag)
{
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex);
g_flag = flag;
pthread_mutex_unlock(&mutex);
return g_flag;
}
可重入函数意味着这个函数可以被中断,
其次意味着它除了使用自己栈上的变量以外不依赖于任何环境。
所以上述example2的函数虽然是线程安全的,但是却不是可重入函数。
因为在lock和unlock之间发生中断时,则mutex永远没有机会去被unlock了。
编写可重入函数时,若使用全局变量,
则应通过disinterruput关中断等手段进行保护。
保证函数既是可重入函数也是线程安全的方法是使用原子操作。
我们在下面这篇博文中对race condition进行了学习,
http://blog.csdn.net/boyxulin1986/article/details/11704257
由此可以知道:
即使对读写都做了mutex保护,也不见得整个操作是安全的;
因为在读操作之后写(或者是访问函数指针等)操作发生之前可能有其它线程做了写操作;
所以这就需要对完整的操作过程做信号量保护。
如果函数只会被单个线程访问,则不必考虑此类问题的发生。