一个低概率bug的定位过程---多线程操作文件时一定要注意

972 篇文章 329 订阅
24 篇文章 11 订阅

         某测试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, 且程序没有一次是崩溃的。

 

 

 

       以后大家遇到多线程环境下的文件操作问题, 一定要注意, 需要增加保护机制, 比如加个互斥锁。

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值