chenyangsocool
WhiteDouglas
采纳率18.2%
2016-01-04 17:33

c语言多线程运行后为什么值会变成这样

已采纳

请问为什么运行下列程序后,gCount的值不为5,而是为一个莫名其妙的随机数啊?
如果说是多线程影响的,那毕竟加和减在两个函数里都限定死了为10000000次,那运算结果应该还是为5啊?
整个运行机制到底是怎样的?
求大神解答!

#include
#include
#include

volatile unsigned int gCount=5;
//gCount是全局共享变量,volatile表明不进行优化

unsigned __stdcall FirstThreadFunc(void *pArguments)
{
int i;
for(i=0;i<10000000;i++)
{
gCount=gCount+1;
}
return 0;
}

unsigned __stdcall SecondThreadFunc(void *pArguments)
{
int i;
for(i=0;i<10000000;i++)
{
gCount=gCount-1;
}
return 0;
}

int main()
{
HANDLE hThread[2];
unsigned threadID[2];

printf("gCount的初始值为%d\n",gCount);

hThread[0]=(HANDLE)_beginthreadex(NULL,0,FirstThreadFunc,NULL,0,&threadID[0]);
hThread[1]=(HANDLE)_beginthreadex(NULL,0,SecondThreadFunc,NULL,0,&threadID[1]);

WaitForSingleObject(hThread[0],INFINITE);
WaitForSingleObject(hThread[1],INFINITE);

CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
printf("并发修改后,gCount的值为%d\n",gCount);

return 0;

}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • Afile Afile 5年前

    应该是线程安全问题。

    点赞 评论 复制链接分享
  • John_ToStr John_ToDebug 5年前

    //线程
    #if 1
    #include
    #include
    #include
    using namespace std;

    //声明关键段(临界区)
    CRITICAL_SECTION g_csNumber;

    //gCount是全局共享变量,volatile表明不进行优化
    volatile unsigned int gCount = 5;

    unsigned __stdcall FirstThreadFunc(void *pArguments)
    {
    //进入临界区
    //g_csNumber的成员OwningThread代表哪个线程
    //拥有临界区,如果OwningThread为NULL,
    //则当前线程进入临界区
    //如果不为空并当和前线程ID
    //不相等则等待
    EnterCriticalSection(&g_csNumber);

    int i;
    for (i = 0; i<10000000; i++)
    {
        gCount = gCount + 1;
    }
    
    //离开临界区
    LeaveCriticalSection(&g_csNumber);
    Sleep(50);
    
    return 0;
    

    }
    unsigned __stdcall SecondThreadFunc(void *pArguments)
    {
    //进入临界区
    //g_csNumber的成员OwningThread代表哪个线程
    //拥有临界区,如果OwningThread为NULL,
    //则当前线程进入临界区
    //如果不为空并当和前线程ID
    //不相等则等待
    EnterCriticalSection(&g_csNumber);

    int i;
    for (i = 0; i<10000000; i++)
    {
        gCount = gCount - 1;
    }
    
    //离开临界区
    LeaveCriticalSection(&g_csNumber);
    return 0;
    

    }
    int main()
    {
    HANDLE hThread[2];
    unsigned threadID[2];
    printf("gCount的初始值为%d\n", gCount);

    //初始化临界区
    InitializeCriticalSection(&g_csNumber);
    
    hThread[0] = (HANDLE)_beginthreadex(NULL, 0, FirstThreadFunc, NULL, 0, &threadID[0]);  //第5个参数,0为运行状态,CREATE_SUSPENDED为挂起状态,阻塞
    hThread[1] = (HANDLE)_beginthreadex(NULL, 0, SecondThreadFunc, NULL, 0, &threadID[1]); //第5个参数,0为运行状态,CREATE_SUSPENDED为挂起状态,阻塞
    
    WaitForSingleObject(hThread[0], INFINITE);  //若为零则不等待,也就不会输出子线程函数里面的内容
    WaitForSingleObject(hThread[1], INFINITE);  //若为零则不等待,也就不会输出子线程函数里面的内容
    
    CloseHandle(hThread[0]);
    CloseHandle(hThread[1]);
    printf("并发修改后,gCount的值为%d\n", gCount);
    
    return 0;
    

    }
    #endif

    以上是我的代码,我加了临界区,保证线程互斥,也就是说在线程一给全局变量加的时候,保证线程二不能够对全局变量进行访问,直到线程一访问完之后,才可以,你还是没有理解多线程问题。

    点赞 评论 复制链接分享

相关推荐