一个函数被称作“线程安全”的,当且仅当它被多个线程反复调用时,它会一直产生令人期待的正确的结果。
反之为“线程不安全”函数,非线程安全的函数主要是由于对全局变量或者静态局部变量进行操作。
可重入函数,是线程安全函数的一种。当它被多个线程调用时,不会对全局变量或静态局部变量进行操作。
也可以用互斥等方法保护全局变量和静态局部变量,使函数变为线程安全的。
#include <stdio.h>
#include <process.h>
#include <windows.h>
//非线程安全
void TestUnsafe(void*)
{
static int ret = 0; //静态局部变量
ret = 0;
for(int i=0; i<10; ++i)
{
::Sleep(200);
ret += i;
}
putchar(ret%10 + '0');
putchar('\n');
}
//利用互斥来保证线程安全
static HANDLE mutex = ::CreateMutex(NULL, false, L"my");
void TestSerial(void*)
{
::WaitForSingleObject(mutex, INFINITE);
TestUnsafe(NULL);
::ReleaseMutex(mutex);
}
//可重入,线程安全
void TestSafe(void*)
{
int ret = 0;
for(int i=0; i<10; ++i)
{
::Sleep(500);
ret += i;
}
putchar(ret%10 + '0');
putchar('\n');
}
int main(int argc, char *argv[])
{
//Test非线程安全
_beginthread(TestUnsafe, 0, NULL);
::Sleep(50);
_beginthread(TestUnsafe, 0, NULL);
getchar();
//Test互斥的线程安全
_beginthread(TestSerial, 0, NULL);
::Sleep(50);
_beginthread(TestSerial, 0, NULL);
getchar();
//Test可重入的线程安全
_beginthread(TestSafe, 0, NULL);
::Sleep(50);
_beginthread(TestSafe, 0, NULL);
getchar();
::CloseHandle(mutex);
return 0;
}