为什么能得到 g_number1 = 1000001, g_number2 = 1000002,g_number2 的值不应该比g_number1 的值大。
// processTest.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <iostream>
#include <Windows.h>using namespace std;DWORD WINAPI ThreadProc(LPVOID lpParameter);CRITICAL_SECTION critical_section;int g_number1;
int g_number2;int _tmain(int argc, _TCHAR* argv[])
{
::InitializeCriticalSection(&critical_section); const int ThreadNumber = 5; HANDLE hthreads[ThreadNumber];
for (int i = 0; i < ThreadNumber;i++)
{
hthreads[i] = ::CreateThread(NULL,0 ,&ThreadProc,NULL,0,NULL);
}

::Sleep(0);//change to another thread ::WaitForMultipleObjects(ThreadNumber,hthreads,false,INFINITE); for (int i = 0; i < ThreadNumber;i++)
{
::CloseHandle(hthreads[i]);
} ::DeleteCriticalSection(&critical_section); cout<<"g_number1 = "<<g_number1<<endl;
cout<<"g_number2 = "<<g_number2<<endl; return 0;
}DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
while(g_number1 < 1000000)
{
::EnterCriticalSection(&critical_section);
Sleep(0);
g_number1++;
g_number2++;
::LeaveCriticalSection(&critical_section);
}
return 0;
}

解决方案 »

  1.   

    会有编译器优化,即将g_number存入缓存中,并不每次都存盘,所以会导致LZ所说的情况g_number加上volatile试试
      

  2.   

    对于那些实时性高的数据
    在声明前加上volatilevolatile int g_number1;
    volatile int g_number2;
      

  3.   

    有可能主线程把临界区delete了,子线程还在跑
      

  4.   

    g_number1 < 1000000
    是不是也应该在临界区内
      

  5.   

    这是我解决g_number1 的值比1000000大的解决方法,不过我不明白g_number1的值为什么会比g_number2大while(g_number1 < 1000000)
    {
    ::EnterCriticalSection(&critical_section);
    Sleep(0);
    if(g_number1 < 1000000)
    {
    g_number1++;
    g_number2++;
    }
    ::LeaveCriticalSection(&critical_section);
    }
      

  6.   


    嗯。看来是不行,问题出在while判断中可以这么写while(true)
    {
    ::EnterCriticalSection(&critical_section);
    Sleep(0);
    if(g_number1 < 1000000)
    {
    g_number1++;
    g_number2++;
    }
    else 
    break;
    ::LeaveCriticalSection(&critical_section);
    }
    }
      

  7.   

    g_number1和g_number2比1000000大很好理解,不过这二个不一样大倒值得深究一下。希望LZ发张g_number2 比g_number1 大的截图。
      

  8.   

    LZ,我猜可能是你代码中的
    ::WaitForMultipleObjects(ThreadNumber,hthreads,false,INFINITE);
    这句写错了。将false改成true再试试。
      

  9.   

    g_number2 比g_number1 大也是因为没有处理同步,如14楼所说的,等待所有线程结束后在进行输出,而不是单个线程结束后就输出
      

  10.   

    改成true确实不会在出现两个值不一样的情况,不过我觉得就算::WaitForMultipleObjects(ThreadNumber,hthreads,false,INFINITE);这样写,也不应该出现g_number2比g_number1大的情况啊。可不可以想象下,线程运行到什么状态下,会出现这种情况吗?
      

  11.   

    主线程加上自己创建的5个线程,在执行过程中可能会出现一下的执行顺序:
    线程1 g_number1++;
    主线程 cout<<g_number1;
    线程1 g_number2++
    线程2 g_number1++;
    线程2 g_number2++;
    主线程 cout<<g_number2;这种执行顺序取决于cpu的给线程分配的执行时间片,会有不确定性的
      

  12.   

    ::EnterCriticalSection(&critical_section);
    Sleep(0);
    把Sleep(0);去掉试试
      

  13.   

    看下操作系统的书知道了,cpu在处理你的num1++,num2++的时候有的时候会给你更改指令的执行顺序,这样num2就有可能比num1大了。记得在操作系统哲学上看到得。
      

  14.   

    答案就在这里,你主线程的写成
    ::WaitForMultipleObjects(ThreadNumber,hthreads,false,INFINITE);
    因此只要有一个子线程执行完,主线程就会输出g_number1和g_number2。这样其他线程就有修改g_number1和g_number2的机会。因此主线程输出现g_number2比g_number1大时很正常的。