某测试MM反馈了一个与文件有关的低概率问题, 我和我带的那个同事(以下简称我们)都没有重现到这个问题。 但是, 某人(我不认识, 也没有见过面)在电话会议中说这个问题多么多么严重, 还把我们骂了一顿, 语言相当龌蹉, 而且非常生硬, 装得很像个啥领导似的。 虽然涛哥我为人随和善良, 工作积极尽责, 但遇到这种满嘴脏话的人, 涛哥也不是好惹的, 结果, 你懂的。 然后对方直接问: 你谁啊?
涛哥懒得鸟他, 直接挂了电话。 这类事情, 虽极少亲自遇到, 但还是见得不少。
有事说事, 有问题搞问题, 别的不跟你多扯。
由于没有重现到问题(每操作一次, 都比较复杂), 且对应的日志也无法发现什么线索。 于是, 我们只有硬看代码可疑的地方了。 后来怀疑是多线程对文件进行了操作才导致的, 最后, 进行对比验证, 发现果真如此。
下面, 先用非常简单的代码来描述一下多线程环境下的文件操作(为了简便, 我就不判断fp是否非空了。 实际应用中, 一定要判断啊):
#include <stdio.h>
#include <windows.h>
void test()
{
FILE *fp = fopen("aaa.txt", "a+");
fprintf(fp, "hello\n");
fclose(fp);
}
DWORD WINAPI ThreadFun(LPVOID pM)
{
test();
return 0;
}
int main()
{
printf("main thread\n");
int i = 0;
while(1)
{
for(i = 0; i < 10; i++)
{
HANDLE handle = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);
CloseHandle(handle);
}
getchar();
}
while(1)
{
;
}
printf("end\n");
return 0;
}
运行这个程序, 然后让while不断循环, 发现文件中并不是每次都打印10个hello, 而且, 我刚才在VC++6.0中运行发现, 经常出现程序崩溃。 下面, 我们对用互斥对象对多线程下的文件操作进行保护(互斥锁), 简要的示意代码如下:
#include <stdio.h>
#include <windows.h>
HANDLE hMutex = NULL;
void test()
{
WaitForSingleObject(hMutex, INFINITE);
FILE *fp = fopen("aaa.txt", "a+");
fprintf(fp, "hello\n");
fclose(fp);
ReleaseMutex(hMutex);
}
DWORD WINAPI ThreadFun(LPVOID pM)
{
test();
return 0;
}
int main()
{
printf("main thread\n");
hMutex = CreateMutex(NULL, FALSE, NULL);
int i = 0;
while(1)
{
for(i = 0; i < 10; i++)
{
HANDLE handle = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL);
CloseHandle(handle);
}
getchar();
}
while(1)
{
;
}
printf("end\n");
return 0;
}
运行该程序, 让while循环50次, 发现每次都打印10个hello, 且程序没有一次是崩溃的。
以后大家遇到多线程环境下的文件操作问题, 一定要注意, 需要增加保护机制, 比如加个互斥锁。