线程有关问题,执行的步骤不懂,请提示下

线程问题,执行的步骤不懂,请提示下。
#include   <stdio.h>
#include   <windows.h>

CRITICAL_SECTION   gcs;

DWORD   threadA(void   *lp);

int   main()
{
        DWORD   Thread_id[3];
        HANDLE   hThread[3];
       
        InitializeCriticalSection(&gcs);         //创建临界区
        //创建线程
        hThread[0]   =   CreateThread(NULL,   0,   (LPTHREAD_START_ROUTINE)threadA,   (void   *)1,   0,   NULL);
        hThread[1]   =   CreateThread(NULL,   0,   (LPTHREAD_START_ROUTINE)threadA,   (void   *)2,   0,   NULL);
        hThread[2]   =   CreateThread(NULL,   0,   (LPTHREAD_START_ROUTINE)threadA,   (void   *)3,   0,   NULL);
        //等待所有线程结束
        WaitForMultipleObjects(3,   hThread,   FALSE,   5000);
        //删除临界区
        printf( "1000\n ");
        DeleteCriticalSection(&gcs);                
        CloseHandle(hThread);
        return   0;
}

DWORD   threadA(void   *lp)
{
        int   id   =   (int)lp;
        int   i   =   0;


        while(i   <   20)
        {
                EnterCriticalSection(&gcs);
                printf( "thread   %d   i   =   %d\n ",   id,   i++);
                LeaveCriticalSection(&gcs);
        }
        return   0;
}

就是while(i   <   20){   }   这里不懂,我想只执行20次,用i   <   20.可线程执行了37次,还有50次,这是为什么。还有用线程怎么才能让它只执行20次?




------解决方案--------------------
三个线程分得的时间片不等,要三个线程全部结束才停止,所以出现了随机的执行次数
------解决方案--------------------
实在不行可以用个volatile 的全局变量代替i
------解决方案--------------------
还有用线程怎么才能让它只执行20次?
============================================
EnterCriticalSection(&gcs);
while(i < 20)
{
printf( "thread %d i = %d\n ", id, i++);
}
LeaveCriticalSection(&gcs);

------解决方案--------------------
WaitForMultipleObjects(3, hThread, FALSE, 5000);
应该为
WaitForMultipleObjects(3, hThread, TRUE, 5000);

线程没有工作顺序,线程是并行的,由于只有一个cpu,所以其实还是串行,一个cpu分配时间片给他们。
------解决方案--------------------
CPU 的分配时间片是以线程为单位的,()
程序的主线程结束时,会强行结束 进程里的所有线程
main 是主线程,
开了hThread[0,1,2]三个工作线程,(和主线程获得CPU的执行权均等)
{四个线程交替运行(中间多加Sleep(0)分看得得清楚}
waitforMulObject (阻塞main主线程)
//waitFor 返回后,你的是hThreada[0]结束了)
剩下的三个线程平行(main又可以继续执行)
到main
return 后
hThead[1,2]还没有结束
在mainCRTStartup开始回收系统资源
强行结束hThead[1,2]这时thread[1,2]的while 还没有结束