再论CreateThread和_beginthreadex


关于这个问题,网上也有很多资料,但却没有找到一个比较满意的答案。
“所有的 C 运行时函数除非 signal() 函数工作正常时使用 CreateThread() 函数创建的线程中。但是,具体取决于哪种 CRT 函数被调用,可能有小的内存泄漏时都将终止线程。调用 strlen(),例如,不会触发的 CRT 线程数据的块、 分配和调用 malloc()、 fopen()、 _open()、 strtok()、 ctime() 或 localtime() 会导致分配的 CRT 每个线程的数据块,这可能会导致内存泄漏。”
-- MSDN Description of using C Run-Time (CRT) functions and CreateThread ()
就连MSDN说的也很隐晦,也说的是"可能导致内存泄露"。

网上也有资料说是tiddata结构没有释放导致了内存泄露,
参考链接: CreateThread 使用不当引起内在泄露? CreateThread 和 _beginthreadex 区别。

但这也是作者一面之词,既然是内存泄露,那应该可以通过一个程序来演示这个内存泄露,想在这里请教下大家,可否提供一个这样的演示程序?

谢谢

多线程 windows

星月无痕ad 12 years, 8 months ago

我曾经用CreateThread()创建的线程里用到基于时间种子的随机数生成,也就是用到了静态缓冲区的runtime函数——rand()函数,结果就算设置了Use MultiThread Lib/DLL随机数总是为0.

   
  #include <windows.h>
  
#include <stdio.h>
#include <conio.h>
#include <ctime>

#define MAX_THREAD_NUM 2

void control_thread( void );
void worker_thread( LPVOID );
double random(int ,int);

int accnt1=0,accnt2=0;//global values
BOOLEAN flag[2]={false,false};
int turn;
struct ThreadParameter//传递线程函数的参数
{
int id;
};
////////////////////////////////////////////////////////
// main fuction
////////////////////////////////////////////////////////

int main( int agrc, char* argv[] )
{
char ch;
srand(unsigned(time(0)));//将时间作为种子
while ( TRUE )
{
accnt1=0;
accnt2=0;
// Cleare screen
system( "cls" );

// display prompt info
printf("*********************************************\n");
printf(" 1.Start test\n");
printf(" 2.Exit to Windows\n");
printf("*********************************************\n");
printf("Input your choice(1or2): ");

// if the number inputed is error, retry!
do{
ch = (char)_getch();
}while( ch != '1' && ch != '2');

system ( "cls" );
if ( ch == '1')
control_thread();
else if ( ch == '2')
return 0;
printf("\nPress any key to finish this Program. \nThank you test this Proggram!\n");
_getch();
} //end while
} //end main
//获取随即数
double random(int start,int end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}

void control_thread()
{
DWORD n_thread = 2;
DWORD thread_ID;
DWORD wait_for_all;
ThreadParameter tp1,tp2;
tp1.id=0;
tp2.id=1;
// Tread Object Array

HANDLE h_Thread[MAX_THREAD_NUM];

// Create thread
h_Thread[0] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(worker_thread), &tp1, 0, &thread_ID);
h_Thread[1] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(worker_thread), &tp2, 0, &thread_ID);

// waiting all thread will been finished

wait_for_all = WaitForMultipleObjects(n_thread,h_Thread,TRUE, -1);
printf("All threads have finished Operating.\n");
}// end

// thread
void worker_thread(LPVOID lpParam)
{
ThreadParameter *tp=(ThreadParameter *)lpParam;//获取参数
int i=tp->id;//线程号
int r=(int)random(0,10);//获取随机数
int j=1-i;// 另外的线程号
//Peterson算法
flag[i]=true;
turn=j;
while(flag[j] && turn==j);//忙等
//临界区
accnt1-=r;
accnt2+=r;
printf("线程%d:accnt1=%d,accnt2=%d.\n",i,accnt1,accnt2);
flag[i]=false;//退出临界区或唤起另外的线程进入临界区
}

shana66 answered 12 years, 8 months ago

Your Answer