是否可以安全地读取正在同时修改而不锁定的整型变量?

时间:2022-05-03 06:49:07

Suppose that I have an integer variable in a class, and this variable may be concurrently modified by other threads. Writes are protected by a mutex. Do I need to protect reads too? I've heard that there are some hardware architectures on which, if one thread modifies a variable, and another thread reads it, then the read result will be garbage; in this case I do need to protect reads. I've never seen such architectures though.

假设在类中有一个整型变量,这个变量可以同时被其他线程修改。写入由互斥体保护。我也需要保护阅读吗?我听说有一些硬件架构,如果一个线程修改一个变量,而另一个线程读取它,那么读取的结果就是垃圾;在这种情况下,我确实需要保护读取。但我从未见过这样的架构。

This question assumes that a single transaction only consists of updating a single integer variable so I'm not worried about the states of any other variables that might also be involved in a transaction.

这个问题假设一个事务只包含更新一个整型变量,所以我不担心任何其他可能也涉及事务的变量的状态。

12 个解决方案

#1


32  

atomic read
As said before, it's platform dependent. On x86, the value must be aligned on a 4 byte boundary. Generally for most platforms, the read must execute in a single CPU instruction.

原子阅读如前所述,它依赖于平台。在x86上,值必须在4字节边界上对齐。通常对于大多数平台,read必须在一个CPU指令中执行。

optimizer caching
The optimizer doesn't know you are reading a value modified by a different thread. declaring the value volatile helps with that: the optimizer will issue a memory read / write for every access, instead of trying to keep the value cached in a register.

优化器缓存优化器不知道正在读取由不同线程修改的值。声明值不稳定会有帮助:优化器将为每个访问发出一个内存读/写,而不是试图将值缓存在寄存器中。

CPU cache
Still, you might read a stale value, since on modern architectures you have multiple cores with individual cache that is not kept in sync automatically. You need a read memory barrier, usually a platform-specific instruction.

仍然是CPU缓存,您可能会读取过时的值,因为在现代架构中,您有多个内核,每个内核的缓存不会自动保持同步。您需要一个读内存屏障,通常是特定于平台的指令。

On Wintel, thread synchronization functions will automatically add a full memory barrier, or you can use the InterlockedXxxx functions.

在Wintel上,线程同步函数将自动添加一个完整的内存屏障,或者您可以使用InterlockedXxxx函数。

MSDN: Memory and Synchronization issues, MemoryBarrier Macro

MSDN:内存和同步问题,MemoryBarrier宏。

[edit] please also see drhirsch's comments.

[编辑]请参阅德赫希的评论。

#2


14  

You ask a question about reading a variable and later you talk about updating a variable, which implies a read-modify-write operation.

您会问一个关于读取变量的问题,然后您会讨论更新一个变量,这意味着一个读-修改-写操作。

Assuming you really mean the former, the read is safe if it is an atomic operation. For almost all architectures this is true for integers.

假设你真的是指前者,如果它是一个原子操作,它是安全的。对于几乎所有的架构来说,对于整数来说都是如此。

There are a few (and rare) exceptions:

有一些(和罕见的)例外:

  • The read is misaligned, for example accessing a 4-byte int at an odd address. Usually you need to force the compiler with special attributes to do some misalignment.
  • 读取是不对齐的,例如访问奇数地址的4字节整数。通常,您需要强制具有特殊属性的编译器执行一些不对齐。
  • The size of an int is bigger than the natural size of instructions, for example using 16 bit ints on a 8 bit architecture.
  • int的大小比指令的自然大小要大,例如在8位架构上使用16位ints。
  • Some architectures have an artificially limited bus width. I only know of very old and outdated ones, like a 386sx or a 68008.
  • 一些架构具有人为限制的总线宽度。我只知道一些很旧过时的,比如386sx或68008。

#3


8  

I'd recommend not to rely on any compiler or architecture in this case.
Whenever you have a mix of readers and writers (as opposed to just readers or just writers) you'd better sync them all. Imagine your code running an artificial heart of someone, you don't really want it to read wrong values, and surely you don't want a power plant in your city go 'boooom' because someone decided not to use that mutex. Save yourself a night-sleep in a long run, sync 'em.
If you only have one thread reading -- you're good to go with just that one mutex, however if you're planning for multiple readers and multiple writers you'd need a sophisticated piece of code to sync that. A nice implementation of read/write lock that would also be 'fair' is yet to be seen by me.

在这种情况下,我建议不要依赖任何编译器或体系结构。当你有读者和作者(而不是仅仅是读者或作家)的混合时,你最好将他们全部同步。想象一下,你的代码运行着一个人的人造心脏,你不希望它读取错误的值,而且你肯定不想在你的城市里有一个发电厂,因为有人决定不使用这个互斥锁。如果你只有一个线程在读取——你最好只读取一个互斥对象,但是如果你打算为多个读者和多个作者进行同步,你就需要一个复杂的代码来同步它。读/写锁的一个很好的实现,也是“公平的”,我还没有看到。

#4


6  

Imagine that you're reading the variable in one thread, that thread gets interrupted while reading and the variable is changed by a writing thread. Now what is the value of the read integer after the reading thread resumes?

假设您正在读取一个线程中的变量,该线程在读取时被中断,而变量被写入线程更改。现在读取线程恢复后读取整数的值是多少?

Unless reading a variable is an atomic operation, in this case only takes a single (assembly) instruction, you can not ensure that the above situation can not happen. (The variable could be written to memory, and retrieving the value would take more than one instruction)

除非读取一个变量是一个原子操作,在本例中只接受单个(汇编)指令,否则无法确保上述情况不会发生。(可以将变量写到内存中,检索该值需要多个指令)

The consensus is that you should encapsulate/lock all writes individualy, while reads can be executed concurrently with (only) other reads

一致的意见是,您应该封装/锁定所有的单独写入,而读取可以与(仅)其他读取同时执行

#5


2  

Suppose that I have an integer variable in a class, and this variable may be concurrently modified by other threads. Writes are protected by a mutex. Do I need to protect reads too? I've heard that there are some hardware architectures on which, if one thread modifies a variable, and another thread reads it, then the read result will be garbage; in this case I do need to protect reads. I've never seen such architectures though.

假设在类中有一个整型变量,这个变量可以同时被其他线程修改。写入由互斥体保护。我也需要保护阅读吗?我听说有一些硬件架构,如果一个线程修改一个变量,而另一个线程读取它,那么读取的结果就是垃圾;在这种情况下,我确实需要保护读取。但我从未见过这样的架构。

In the general case, that is potentially every architecture. Every architecture has cases where reading concurrently with a write will result in garbage. However, almost every architecture also has exceptions to this rule.

在一般情况下,这可能是每个架构。每个体系结构都有这样的情况,即与写入同时读取将导致垃圾。然而,几乎所有的体系结构都有例外。

It is common that word-sized variables are read and written atomically, so synchronization is not needed when reading or writing. The proper value will be written atomically as a single operation, and threads will read the current value as a single atomic operation as well, even if another thread is writing. So for integers, you're safe on most architectures. Some will extend this guarantee to a few other sizes as well, but that's obviously hardware-dependant.

一般来说,文字大小的变量都是通过原子的方式读取和写入的,所以在阅读或写入时不需要同步。适当的值将作为单个操作原子地写入,并且线程也将把当前值作为单个原子操作读取,即使另一个线程正在写入。对于整数,在大多数体系结构上都是安全的。有些还会将此保证扩展到其他一些大小,但这显然是硬件依赖的。

For non-word-sized variables both reading and writing will typically be non-atomic, and will have to be synchronized by other means.

对于非文字大小的变量,读写通常都是非原子的,必须通过其他方式进行同步。

#6


1  

If you don't use prevous value of this variable when write new, then:

如果在写入new时不使用该变量的prevous值,则:

  You can read and write integer variable without using mutex. It is because integer is base type in 32bit architecture and every modification/read of value is doing with one operation.

您可以不使用互斥量来读写整型变量。这是因为integer是32位架构中的基类型,每次值的修改/读取都是通过一个操作完成的。

But, if you donig something such as increment:

但是,如果你做了一些事情,比如增加:

myvar++;

  Then you need use mutex, because this construction is expanded to myvar = myvar + 1 and between read myvar and increment myvar, myvar can be modified. In that case you will get bad value.

然后需要使用互斥,因为这个构造被扩展到myvar = myvar + 1,在read myvar和increment myvar之间,可以修改myvar。在这种情况下,你会得到不好的价值。

#7


1  

While it would probably be safe to read ints on 32 bit systems without synchronization. I would not risk it. While multiple concurrent reads are not a problem, I do not like writes to happen at the same time as reads.

虽然在32位系统上读取ints可能是安全的,但没有同步。我不会冒这个险。虽然多次并发读取不是问题,但我不希望写入与读取同时发生。

I would recommend placing the reads in the Critical Section too and then stress test your application on multiple cores to see if this is causing too much contention. Finding concurrency bugs is a nightmare I prefer to avoid. What happens if in the future some one decides to change the int to a long long or a double, so they can hold larger numbers?

我建议将读取也放在关键部分,然后在多个核心上对应用程序进行压力测试,看看这是否导致了太多的争用。查找并发bug是我宁愿避免的噩梦。如果将来有人决定把整数换成长整数或者双整数,这样他们就能容纳更大的数,会发生什么呢?

If you have a nice thread library like boost.thread or zthread then you should have read/writer locks. These would be ideal for your situation as they allow multiple reads while protecting writes.

如果你有一个很好的线程库,比如boost。线程或zthread那么您应该具有读/写锁。这些将非常适合您的情况,因为它们允许在保护写操作的同时进行多次读取。

#8


0  

This may happen on 8 bit systems which use 16 bit integers.

这可能发生在使用16位整数的8位系统上。

If you want to avoid locking you can under suitable circumstances get away with reading multiple times, until you get two equal consecutive values. For example, I've used this approach to read the 64 bit clock on a 32 bit embedded target, where the clock tick was implemented as an interrupt routine. In that case reading three times suffices, because the clock can only tick once in the short time the reading routine runs.

如果希望避免锁定,可以在适当的情况下多次读取,直到得到两个相等的连续值。例如,我使用了这种方法来读取32位嵌入式目标上的64位时钟,在那里时钟滴答被作为中断例程来实现。在这种情况下,阅读三次就足够了,因为时钟在短时间内只能运行一次。

#9


0  

Both reading / writing to variables with concurrency must be protected by a critical section (not mutex). Unless you want to waste your whole day debugging.

对具有并发性的变量的读写都必须由关键部分(而不是互斥)保护。除非你想浪费一整天的调试时间。

Critical sections are platform-specific, I believe. On Win32, critical section is very efficient: when no interlocking occur, entering critical section is almost free and does not affect overall performance. When interlocking occur, it is still more efficient, than mutex, because it implements a series of checks before suspending the thread.

我认为,关键部分是特定于平台的。在Win32上,critical section非常高效:当没有联锁发生时,进入critical section几乎是免费的,不会影响整体性能。当发生联锁时,它仍然比互斥锁更有效,因为它在挂起线程之前实现了一系列的检查。

#10


0  

In general, each machine instruction goes thru several hardware stages when executing. As most current CPUs are multi-core or hyper-threaded, that means that reading a variable may start it moving thru the instruction pipeline, but it doesn't stop another CPU core or hyper-thread from concurrently executing a store instruction to the same address. The two concurrently executing instructions, read and store, might "cross paths", meaning that the read will receive the old value just before the new value is stored.
To resume: you do need the mutex for both read and writes.

通常,每条机器指令在执行时都要经过几个硬件阶段。由于大多数当前的CPU都是多核或超线程的,这意味着读取一个变量可能会启动它通过指令管道移动,但它不会阻止另一个CPU核心或超线程同时执行存储指令到同一个地址。这两个同时执行的指令read和store可能会“交叉路径”,这意味着read将在存储新值之前接收旧值。要继续:读写都需要互斥锁。

#11


-1  

Depends on your platform. Most modern platforms offer atomic operations for integers: Windows has InterlockedIncrement, InterlockedDecrement, InterlockedCompareExchange, etc. These operations are usually supported by the underlying hardware (read: the CPU) and they are usually cheaper than using a critical section or other synchronization mechanisms.

取决于你的平台。大多数现代平台都提供整数的原子操作:Windows有InterlockedIncrement、interlockeddec量、InterlockedCompareExchange等等。这些操作通常由底层硬件(读:CPU)支持,并且它们通常比使用临界段或其他同步机制更便宜。

See MSDN: InterlockedCompareExchange

看到MSDN:InterlockedCompareExchange

I believe Linux (and modern Unix variants) support similar operations in the pthreads package but I don't claim to be an expert there.

我相信Linux(以及现代的Unix变体)支持pthreads包中的类似操作,但我并不是这方面的专家。

#12


-3  

If a variable is marked with the volatile keyword then the read/write becomes atomic but this has many, many other implications in terms of what the compiler does and how it behaves and shouldn't just be used for this purpose.

如果一个变量被用volatile关键字标记,那么读/写就变成了原子,但是这在编译器做什么以及它的行为方面有很多其他的含义,不应该仅仅用于这个目的。

Read up on what volatile does before you blindly start using it: http://msdn.microsoft.com/en-us/library/12a04hfd(VS.80).aspx

在盲目使用volatile之前,请仔细阅读它的作用:http://msdn.microsoft.com/en-us/library/12a04hfd(VS.80).aspx

#1


32  

atomic read
As said before, it's platform dependent. On x86, the value must be aligned on a 4 byte boundary. Generally for most platforms, the read must execute in a single CPU instruction.

原子阅读如前所述,它依赖于平台。在x86上,值必须在4字节边界上对齐。通常对于大多数平台,read必须在一个CPU指令中执行。

optimizer caching
The optimizer doesn't know you are reading a value modified by a different thread. declaring the value volatile helps with that: the optimizer will issue a memory read / write for every access, instead of trying to keep the value cached in a register.

优化器缓存优化器不知道正在读取由不同线程修改的值。声明值不稳定会有帮助:优化器将为每个访问发出一个内存读/写,而不是试图将值缓存在寄存器中。

CPU cache
Still, you might read a stale value, since on modern architectures you have multiple cores with individual cache that is not kept in sync automatically. You need a read memory barrier, usually a platform-specific instruction.

仍然是CPU缓存,您可能会读取过时的值,因为在现代架构中,您有多个内核,每个内核的缓存不会自动保持同步。您需要一个读内存屏障,通常是特定于平台的指令。

On Wintel, thread synchronization functions will automatically add a full memory barrier, or you can use the InterlockedXxxx functions.

在Wintel上,线程同步函数将自动添加一个完整的内存屏障,或者您可以使用InterlockedXxxx函数。

MSDN: Memory and Synchronization issues, MemoryBarrier Macro

MSDN:内存和同步问题,MemoryBarrier宏。

[edit] please also see drhirsch's comments.

[编辑]请参阅德赫希的评论。

#2


14  

You ask a question about reading a variable and later you talk about updating a variable, which implies a read-modify-write operation.

您会问一个关于读取变量的问题,然后您会讨论更新一个变量,这意味着一个读-修改-写操作。

Assuming you really mean the former, the read is safe if it is an atomic operation. For almost all architectures this is true for integers.

假设你真的是指前者,如果它是一个原子操作,它是安全的。对于几乎所有的架构来说,对于整数来说都是如此。

There are a few (and rare) exceptions:

有一些(和罕见的)例外:

  • The read is misaligned, for example accessing a 4-byte int at an odd address. Usually you need to force the compiler with special attributes to do some misalignment.
  • 读取是不对齐的,例如访问奇数地址的4字节整数。通常,您需要强制具有特殊属性的编译器执行一些不对齐。
  • The size of an int is bigger than the natural size of instructions, for example using 16 bit ints on a 8 bit architecture.
  • int的大小比指令的自然大小要大,例如在8位架构上使用16位ints。
  • Some architectures have an artificially limited bus width. I only know of very old and outdated ones, like a 386sx or a 68008.
  • 一些架构具有人为限制的总线宽度。我只知道一些很旧过时的,比如386sx或68008。

#3


8  

I'd recommend not to rely on any compiler or architecture in this case.
Whenever you have a mix of readers and writers (as opposed to just readers or just writers) you'd better sync them all. Imagine your code running an artificial heart of someone, you don't really want it to read wrong values, and surely you don't want a power plant in your city go 'boooom' because someone decided not to use that mutex. Save yourself a night-sleep in a long run, sync 'em.
If you only have one thread reading -- you're good to go with just that one mutex, however if you're planning for multiple readers and multiple writers you'd need a sophisticated piece of code to sync that. A nice implementation of read/write lock that would also be 'fair' is yet to be seen by me.

在这种情况下,我建议不要依赖任何编译器或体系结构。当你有读者和作者(而不是仅仅是读者或作家)的混合时,你最好将他们全部同步。想象一下,你的代码运行着一个人的人造心脏,你不希望它读取错误的值,而且你肯定不想在你的城市里有一个发电厂,因为有人决定不使用这个互斥锁。如果你只有一个线程在读取——你最好只读取一个互斥对象,但是如果你打算为多个读者和多个作者进行同步,你就需要一个复杂的代码来同步它。读/写锁的一个很好的实现,也是“公平的”,我还没有看到。

#4


6  

Imagine that you're reading the variable in one thread, that thread gets interrupted while reading and the variable is changed by a writing thread. Now what is the value of the read integer after the reading thread resumes?

假设您正在读取一个线程中的变量,该线程在读取时被中断,而变量被写入线程更改。现在读取线程恢复后读取整数的值是多少?

Unless reading a variable is an atomic operation, in this case only takes a single (assembly) instruction, you can not ensure that the above situation can not happen. (The variable could be written to memory, and retrieving the value would take more than one instruction)

除非读取一个变量是一个原子操作,在本例中只接受单个(汇编)指令,否则无法确保上述情况不会发生。(可以将变量写到内存中,检索该值需要多个指令)

The consensus is that you should encapsulate/lock all writes individualy, while reads can be executed concurrently with (only) other reads

一致的意见是,您应该封装/锁定所有的单独写入,而读取可以与(仅)其他读取同时执行

#5


2  

Suppose that I have an integer variable in a class, and this variable may be concurrently modified by other threads. Writes are protected by a mutex. Do I need to protect reads too? I've heard that there are some hardware architectures on which, if one thread modifies a variable, and another thread reads it, then the read result will be garbage; in this case I do need to protect reads. I've never seen such architectures though.

假设在类中有一个整型变量,这个变量可以同时被其他线程修改。写入由互斥体保护。我也需要保护阅读吗?我听说有一些硬件架构,如果一个线程修改一个变量,而另一个线程读取它,那么读取的结果就是垃圾;在这种情况下,我确实需要保护读取。但我从未见过这样的架构。

In the general case, that is potentially every architecture. Every architecture has cases where reading concurrently with a write will result in garbage. However, almost every architecture also has exceptions to this rule.

在一般情况下,这可能是每个架构。每个体系结构都有这样的情况,即与写入同时读取将导致垃圾。然而,几乎所有的体系结构都有例外。

It is common that word-sized variables are read and written atomically, so synchronization is not needed when reading or writing. The proper value will be written atomically as a single operation, and threads will read the current value as a single atomic operation as well, even if another thread is writing. So for integers, you're safe on most architectures. Some will extend this guarantee to a few other sizes as well, but that's obviously hardware-dependant.

一般来说,文字大小的变量都是通过原子的方式读取和写入的,所以在阅读或写入时不需要同步。适当的值将作为单个操作原子地写入,并且线程也将把当前值作为单个原子操作读取,即使另一个线程正在写入。对于整数,在大多数体系结构上都是安全的。有些还会将此保证扩展到其他一些大小,但这显然是硬件依赖的。

For non-word-sized variables both reading and writing will typically be non-atomic, and will have to be synchronized by other means.

对于非文字大小的变量,读写通常都是非原子的,必须通过其他方式进行同步。

#6


1  

If you don't use prevous value of this variable when write new, then:

如果在写入new时不使用该变量的prevous值,则:

  You can read and write integer variable without using mutex. It is because integer is base type in 32bit architecture and every modification/read of value is doing with one operation.

您可以不使用互斥量来读写整型变量。这是因为integer是32位架构中的基类型,每次值的修改/读取都是通过一个操作完成的。

But, if you donig something such as increment:

但是,如果你做了一些事情,比如增加:

myvar++;

  Then you need use mutex, because this construction is expanded to myvar = myvar + 1 and between read myvar and increment myvar, myvar can be modified. In that case you will get bad value.

然后需要使用互斥,因为这个构造被扩展到myvar = myvar + 1,在read myvar和increment myvar之间,可以修改myvar。在这种情况下,你会得到不好的价值。

#7


1  

While it would probably be safe to read ints on 32 bit systems without synchronization. I would not risk it. While multiple concurrent reads are not a problem, I do not like writes to happen at the same time as reads.

虽然在32位系统上读取ints可能是安全的,但没有同步。我不会冒这个险。虽然多次并发读取不是问题,但我不希望写入与读取同时发生。

I would recommend placing the reads in the Critical Section too and then stress test your application on multiple cores to see if this is causing too much contention. Finding concurrency bugs is a nightmare I prefer to avoid. What happens if in the future some one decides to change the int to a long long or a double, so they can hold larger numbers?

我建议将读取也放在关键部分,然后在多个核心上对应用程序进行压力测试,看看这是否导致了太多的争用。查找并发bug是我宁愿避免的噩梦。如果将来有人决定把整数换成长整数或者双整数,这样他们就能容纳更大的数,会发生什么呢?

If you have a nice thread library like boost.thread or zthread then you should have read/writer locks. These would be ideal for your situation as they allow multiple reads while protecting writes.

如果你有一个很好的线程库,比如boost。线程或zthread那么您应该具有读/写锁。这些将非常适合您的情况,因为它们允许在保护写操作的同时进行多次读取。

#8


0  

This may happen on 8 bit systems which use 16 bit integers.

这可能发生在使用16位整数的8位系统上。

If you want to avoid locking you can under suitable circumstances get away with reading multiple times, until you get two equal consecutive values. For example, I've used this approach to read the 64 bit clock on a 32 bit embedded target, where the clock tick was implemented as an interrupt routine. In that case reading three times suffices, because the clock can only tick once in the short time the reading routine runs.

如果希望避免锁定,可以在适当的情况下多次读取,直到得到两个相等的连续值。例如,我使用了这种方法来读取32位嵌入式目标上的64位时钟,在那里时钟滴答被作为中断例程来实现。在这种情况下,阅读三次就足够了,因为时钟在短时间内只能运行一次。

#9


0  

Both reading / writing to variables with concurrency must be protected by a critical section (not mutex). Unless you want to waste your whole day debugging.

对具有并发性的变量的读写都必须由关键部分(而不是互斥)保护。除非你想浪费一整天的调试时间。

Critical sections are platform-specific, I believe. On Win32, critical section is very efficient: when no interlocking occur, entering critical section is almost free and does not affect overall performance. When interlocking occur, it is still more efficient, than mutex, because it implements a series of checks before suspending the thread.

我认为,关键部分是特定于平台的。在Win32上,critical section非常高效:当没有联锁发生时,进入critical section几乎是免费的,不会影响整体性能。当发生联锁时,它仍然比互斥锁更有效,因为它在挂起线程之前实现了一系列的检查。

#10


0  

In general, each machine instruction goes thru several hardware stages when executing. As most current CPUs are multi-core or hyper-threaded, that means that reading a variable may start it moving thru the instruction pipeline, but it doesn't stop another CPU core or hyper-thread from concurrently executing a store instruction to the same address. The two concurrently executing instructions, read and store, might "cross paths", meaning that the read will receive the old value just before the new value is stored.
To resume: you do need the mutex for both read and writes.

通常,每条机器指令在执行时都要经过几个硬件阶段。由于大多数当前的CPU都是多核或超线程的,这意味着读取一个变量可能会启动它通过指令管道移动,但它不会阻止另一个CPU核心或超线程同时执行存储指令到同一个地址。这两个同时执行的指令read和store可能会“交叉路径”,这意味着read将在存储新值之前接收旧值。要继续:读写都需要互斥锁。

#11


-1  

Depends on your platform. Most modern platforms offer atomic operations for integers: Windows has InterlockedIncrement, InterlockedDecrement, InterlockedCompareExchange, etc. These operations are usually supported by the underlying hardware (read: the CPU) and they are usually cheaper than using a critical section or other synchronization mechanisms.

取决于你的平台。大多数现代平台都提供整数的原子操作:Windows有InterlockedIncrement、interlockeddec量、InterlockedCompareExchange等等。这些操作通常由底层硬件(读:CPU)支持,并且它们通常比使用临界段或其他同步机制更便宜。

See MSDN: InterlockedCompareExchange

看到MSDN:InterlockedCompareExchange

I believe Linux (and modern Unix variants) support similar operations in the pthreads package but I don't claim to be an expert there.

我相信Linux(以及现代的Unix变体)支持pthreads包中的类似操作,但我并不是这方面的专家。

#12


-3  

If a variable is marked with the volatile keyword then the read/write becomes atomic but this has many, many other implications in terms of what the compiler does and how it behaves and shouldn't just be used for this purpose.

如果一个变量被用volatile关键字标记,那么读/写就变成了原子,但是这在编译器做什么以及它的行为方面有很多其他的含义,不应该仅仅用于这个目的。

Read up on what volatile does before you blindly start using it: http://msdn.microsoft.com/en-us/library/12a04hfd(VS.80).aspx

在盲目使用volatile之前,请仔细阅读它的作用:http://msdn.microsoft.com/en-us/library/12a04hfd(VS.80).aspx