• 多线程读取全局变量


      题目:

    int global = 0;
    
    // thread 1
    for(int i = 0; i < 10; ++i)
    global -= 1;
    
    // thread 2
    for(int i = 0; i < 10; ++i)
    global += 1;

      之后global的可能的值是多少(多种可能)?

      这个问题考虑的是全局变量global的加减操作不是原子操作,在加减过程中有可能被打断,从而产生的结果与预期不一样。上述global加减操作的汇编如下

    ;windows下加操作
    mov eax,dword ptr [globle (10A9148h)] 
    add eax,1 
    mov dword ptr [globle (10A9148h)],eax 
    
    ;windows下减操作
    mov eax,dword ptr [globle (10A9148h)] 
    sub eax,1 
    mov dword ptr [globle (10A9148h)],eax 
    
    ;linux下加操作
    movl global, %eax
    addl $1, %eax
    movl %eax, global
    
    ;linux下减操作
    movl global, %eax
    subl $1, %eax
    movl %eax, global

      可见,不论加减都要经过global的值加载到eax,然后eax加减1,最后再写回global中。这时如果线程1的global的值刚加载到eax中,线程2获取到了执行权,就会出现问题。具体看下面例子。

      假设操作前global值为5。

      线程1                                                                                                                  线程2

      movl global,%eax;global值为5,%eax值为5

      addl $1,%eax;%eax值为6

                                                                       ------此时线程2获取执行权限--------->

                                                                                                                               movl global,%eax;global值为5,%eax值为5

                                                                                                                               subl $1,%eax;%eax值为4

                                                                                                                               movl %eax,global;%eax值为4,global值为4

                                                                     <--------执行权交回线程1-------------- 

      movl %eax,global;%eax值为4,global值为4

      由上述例子可以看出,结果并非我们预计的global的值加1减1后仍保持原值,而是由5变为了4。这就是多线程下非原子操作有可能产生的问题。

      所以题目global输出并非0一种可能。global的加减操作有可能失效,所以global的结果应分布在-10到10之间。

  • 相关阅读:
    Tomcat服务器本地的搭建,以及在 IDEA软件下的配置,以及项目的测试运行(基于supermvc框架下的web)
    数据可视化-EChart2.0.0使用中遇到的2个问题
    数据可视化-EChart2.0使用总结2
    数据可视化-EChart2.0使用总结1
    Mac下有道笔记本问题反馈
    修复bootstrap daterangepicker中的3个问题
    使用jQuery封装实用函数
    Web Fundamentsals学习1-Multiple-Screen-Site
    安装Git
    学会使用Git创建分支
  • 原文地址:https://www.cnblogs.com/budapeng/p/3300679.html
Copyright © 2020-2023  润新知