全局变量和线程 [英] Global variables and threads

查看:50
本文介绍了全局变量和线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个全局计数器并且我有两个线程,每个线程都在循环中将其递增 100 次,为什么我可以使用 200 以外的值?我不明白如何访问变量是非原子的.

If I have a global counter and I have two threads that are each incrementing it 100 times in a loop, why is it possible that I can have a value other than 200? I don't see how accessing the variable is nonatomic.

推荐答案

那是因为对于大多数环境,增加内存位置不是原子操作.

That is because for most environments, incrementing a memory location is not an atomic operation.

事件的顺序类似于

  • 编译器将值 0 放在内存地址 0xABCD 处
  • 线程 1 将 0xABCD 读入寄存器并递增寄存器值
  • 线程 1 被线程 2 中断
  • 线程 2 从内存地址 0xABCD 读取值 0 到寄存器中
  • 线程 2 递增寄存器中的值
  • 线程 2 将寄存器中的值写入 0xABCD
  • 线程 2 从 0xABCD 读取值 1,增加寄存器,然后再次写回
  • 线程 1 恢复
  • 线程 1 将其寄存器 1 中的值写入 0xABCD,覆盖线程 2 先前写入的值 2.

为了确保一致的结果,您必须使增量操作具有原子性.这通常通过在增量操作周围放置线程锁来完成.例如,在 C# 中可能看起来像

To ensure a consistent result, you must make the increment operation atomic. This is often done by placing a thread lock around the increment operation. For example, in C# that might look like

object mylock = new object();
...
lock (mylock) 
{ 
    myInt++;
}

或者,在 .NET 环境中,可以使用 Interlocked.Increment

Alternatively, in the .NET environment, one could use Interlocked.Increment

http://msdn.microsoft.com/en-us/library/dd78zt0c.aspx

其他环境也有类似的结构.

Other environments have similar constructs.

我在 .NET 环境中遇到的关于线程的最佳参考(但无论您的环境如何都是有用的阅读)如下

The best reference I have ever come across for threading in the .NET environment (but is a useful read no matter what your environment) is the following

http://www.albahari.com/threading/

这篇关于全局变量和线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆