设为首页 加入收藏

TOP

C语言多线程中变量累加问题的分析(一)
2015-11-25 13:22:09 来源: 作者: 【 】 浏览:66
Tags:语言 线程 变量 问题 分析

问题:请问下面程序中,main函数打印出的g_iTestInteger变量的值是多少?

/**********************************************************************
* 版权所有 (C)2015, Zhou Zhaoxiong。
*
* 文件名称:MultipleThread_1.c
* 文件标识:无
* 内容摘要:多线程中的变量值问题
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20151117
*
**********************************************************************/
#include 
   
     #include 
    
      #include 
     
       // 重定义数据类型 typedef signed int INT32; typedef unsigned int UINT32; // 宏定义 #define THREAD_NUM 100 // 线程个数 // 全局变量 UINT32 g_iTestInteger = 0; // 函数声明 void ProcessTask(void *pParam); /********************************************************************** * 功能描述:主函数 * 输入参数:无 * 输出参数:无 * 返 回 值:无 * 其它说明:无 * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------------- * 20151117 V1.0 Zhou Zhaoxiong 创建 ***********************************************************************/ INT32 main() { pthread_t MultiHandle = 0; // 多线程句柄 pthread_t SingleHandle = 0; // 单线程句柄 UINT32 iLoopFlag = 0; INT32 iRetVal = 0; // 创建线程函数的返回值 // 循环创建线程 for (iLoopFlag = 0; iLoopFlag < THREAD_NUM; iLoopFlag ++) { iRetVal = pthread_create(&MultiHandle, NULL, (void * (*)(void *))(&ProcessTask), (void *)iLoopFlag); if (0 != iRetVal) { printf(Create ProcessTask %d failed! , iLoopFlag); return -1; } } // 打印全局变量的值 printf(In main, TestInteger = %d , g_iTestInteger); return 0; } /********************************************************************** * 功能描述: 处理线程 * 输入参数: pParam-线程编号 * 输出参数: 无 * 返 回 值: 无 * 其它说明: 无 * 修改日期 版本号 修改人 修改内容 * ---------------------------------------------------------------------- * 20151117 V1.0 Zhou Zhaoxiong 创建 ************************************************************************/ void ProcessTask(void *pParam) { g_iTestInteger ++; }
     
    
   

以上程序的功能比较简单,就是创建100个相同的线程,在线程中对g_iTestInteger的值进行累加,然后在main函数中打印g_iTestInteger的值。

看到这个程序,大家可能会说g_iTestInteger变量的值应该是100,因为每个线程都对g_iTestInteger加了1次。好吧,我们先运行程序,看下打印出来的结果是多少。

我们将程序上传到Linux机器上,然后执行如下操作:

~/zhouzhaoxiong/zzx/MultipleThread> gcc -g -o MultipleThread MultipleThread_1.c -lpthread
~/zhouzhaoxiong/zzx/MultipleThread> MultipleThread
In main, TestInteger = 99
~/zhouzhaoxiong/zzx/MultipleThread> MultipleThread
In main, TestInteger = 99
~/zhouzhaoxiong/zzx/MultipleThread> MultipleThread
In main, TestInteger = 99
~/zhouzhaoxiong/zzx/MultipleThread> MultipleThread
In main, TestInteger = 98
~/zhouzhaoxiong/zzx/MultipleThread> MultipleThread
In main, TestInteger = 99

出乎大多数人的意料,g_iTestInteger变量的值不但不是100,而且不是固定的值。在这里,我只是运行了五次程序,大家可以多运行几次,看结果会不会是100。

那么,为什么结果不是100呢?为了查找原因,我们在“g_iTestInteger ++;”代码之后将g_iTestInteger变量的值打印出来,如下代码所示:

/**********************************************************************
* 版权所有 (C)2015, Zhou Zhaoxiong。
*
* 文件名称:MultipleThread_2.c
* 文件标识:无
* 内容摘要:多线程中的变量值问题
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20151117
*
**********************************************************************/
#include 
   
     #include 
    
      #include 
     
       // 重定义数据类型 typedef signed int INT32; typedef unsigned int UINT32; // 宏定义 #define THREAD_NUM 100 // 线程个数 // 全局变量 UINT32 g_iTestInteger = 0; // 函数声明 void ProcessTask(void *pParam); /********************************************************************** * 功能描述:主函数 * 输入参数:无 * 输出参数:无 * 返 回 值:无 * 其它说明:无 * 修改日期 版本号 修改人 修改内容 * ------------------------------------------------------------------- * 20151117 V1.0 Zhou Zhaoxiong 创建 ***********************************************************************/ INT32 main() { pthread_t MultiHandle = 0; // 多线程句柄 pthread_t SingleHandle = 0; // 单线程句柄 UINT32 iLoopFlag = 0; INT32 iRetVal = 0; // 创建线程函数的返回值 // 循环创建线程 for (iLoopFlag = 0; iLoopFlag < THREAD_NUM; iLoopFlag ++) { iRetVal = pthread_create(&MultiHandle, NULL, (void * (*)(void *))(&ProcessTask), (void *)iLoopFlag); if (0 != iRetVal) { printf(Create ProcessTask %d failed! , iLoopFlag); return -1; } } // 打印全局变量的值 printf(In main, TestInteger = %d , g_iTestInteger); return 0; } /********************************************************************** * 功能描述: 处理线程 * 输入参数: pParam-线程编号 * 输出参数: 无 * 返 回 值: 无 * 其它说明: 无 * 修改日期 版本号 修改人 修改内容 * ---------------------------------------------------------------------- * 20151117 V1.0 Zhou Zhaoxiong 创建 ************************************************************************/ void ProcessTask(void *pParam) { g_iTestInteger ++; printf(TestInteger = %d , g_iTestInteger); }
     
    
   

重新上传程序,编译并执行,如下:

TestInteger = 1
TestInteger = 3
TestInteger = 2
TestInteger = 4
TestInteger = 5
TestInteger = 6
TestInteger = 26
TestInteger = 7
TestInteger = 8
TestInteger = 9
TestInteger = 10
TestInteger = 11
TestInteger = 12
TestInteger = 13
TestInteger = 27
TestInteger = 15
TestInteger = 16
TestInteger = 17
TestInteger = 18
TestInteger = 19
TestInteger = 20
TestInteger = 21
TestInt

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇没有了 下一篇[C语言]模拟计算器

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: