下面代码运行显示结果如图;为什么会有相同的线程编号?
    #include <stdio.h>  
    #include <process.h>  
    #include <windows.h>  
    long g_nNum;  
    unsigned int __stdcall Fun(void *pPM);  
    const int THREAD_NUM = 10;  
    //关键段变量声明  
    CRITICAL_SECTION  g_csThreadParameter, g_csThreadCode;  
    int main()  
    {  
 HANDLE  handle[10]; 
  int i = 0;
 
        //关键段初始化  
        InitializeCriticalSection(&g_csThreadParameter);  
        InitializeCriticalSection(&g_csThreadCode);  
          
         
        g_nNum = 0;   
         
        while (i < THREAD_NUM)   
        {  
            EnterCriticalSection(&g_csThreadParameter);//进入子线程序号关键区域  
            handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL); 
LeaveCriticalSection(&g_csThreadParameter);//离开子线程序号关键区域  
            ++i;  
        }  
        WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);  
      
        DeleteCriticalSection(&g_csThreadCode);  
        DeleteCriticalSection(&g_csThreadParameter);  
        return 0;  
    }  
    unsigned int __stdcall Fun(void *pPM)  
    {  
 
        int nThreadNum = *(int *)pPM;   
        Sleep(50);//some work should to do  
        EnterCriticalSection(&g_csThreadCode);//进入各子线程互斥区域  
        g_nNum++;  
        Sleep(0);//some work should to do  
        printf("线程编号为%d  全局资源值为%d\n", nThreadNum, g_nNum);  
        LeaveCriticalSection(&g_csThreadCode);//离开各子线程互斥区域  
        return 0;  
    }  

解决方案 »

  1.   

    选择使用MFC库,静态或者动态都可以
      

  2.   

    /ML(缺省选项)对应单线程静态版的标准程序库(libc.lib);
    /MLd对应调试版单线程静态标准库(libcd.lib),VC6默认是以单线程库运行的,如果你创建的是win32 console application
      

  3.   

    你传的是一个int变量地址进去。当执行完handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);的时候,线程并没有立即开始,接着你又继续创建线程.线程开始时间不确定,所以当到printf("线程编号为%d  全局资源值为%d\n", nThreadNum, g_nNum);  时,可能读取的是同一个值.
      

  4.   

      while (i < THREAD_NUM)   
            {      
                EnterCriticalSection(&g_csThreadParameter);//进入子线程序号关键区域  
                handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL); 
                LeaveCriticalSection(&g_csThreadParameter);//离开子线程序号关键区域  
                ++i;  
            }  比如创建了1线程,这个时候i为0,退出临界区,然后又继续创建了2线程,这个时候i是1.。。但是1线程可能刚刚执行,但是i已经变了,因为你传到线程中的参数是i的指针地址。
      

  5.   

    Project->Settings->C/C++->Code Generation->Use run-time libray->Debug Multithread,或 Multithread,或 Debug Multithread DLL, 或 Multithread DLL
    我是这样设置;
      

  6.   

    要像g_nNum一样在外部定义一个全局变量来
    //int nThreadNum = *(int *)pPM;   
            Sleep(50);//some work should to do  
            EnterCriticalSection(&g_csThreadCode);//进入各子线程互斥区域  
    g_nThreadNum++;
            g_nNum++;  
            Sleep(0);//some work should to do  
            printf("线程编号为%d  全局资源值为%d\n", g_nThreadNum, g_nNum);  
            LeaveCriticalSection(&g_csThreadCode);//离开各子线程互斥区域  
      

  7.   

    恩,对,传递i即可,不要传i的地址。
    handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, (LPVOID)i, 0, NULL); 
    线程函数中也要修改一下:
    int nThreadNum = (int)pPM;  
      

  8.   

    感觉你没有说清楚相同的原因;
    他已经说清楚了,你传递的是i的地址,而不是i本身的值,就好比你传递的是指针,并不是指针的值,这个指针的值可能后来会被修改,所以你通过*p得到指针的值就可能是修改后的值。
      

  9.   

    恩,对,传递i即可,不要传i的地址。
    handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, (LPVOID)i, 0, NULL); 
    线程函数中也要修改一下:
    int nThreadNum = (int)pPM;  正解,可以了。