现在的位置: 首页 > 综合 > 正文

Thread-Safety with the Interlocked Class(Synchronization of .net)

2012年01月03日 ⁄ 综合 ⁄ 共 3193字 ⁄ 字号 评论关闭
文章目录

Thread-Safety with the Interlocked Class

When developing multi-threaded software or using parallel programming techniques, it is essential that classes remain thread-safe. The Interlocked class provides methods that assist with thread safety by performing atomic operations. 

Thread-Safety

When you are using the task parallel library to parallelise your code, or when writing multi-threaded applications, you must ensure that your code is thread-safe. This means that any data that is shared by multiple threads must be accessed in a manner that ensures that threads cannot interfere with each other's results.

Some standard operations provided by C# and the .NET framework are not thread-safe, even though they may appear to be. For example, you might assume that the increment operator(++) performs an atomic operation. However, in reality incrementing a variable's value involves reading the value, updating the read value and writing the updated value back into the variable. If two threads attempt to increment a value simultaneously a race condition may occur and it is possible that the value be increased only by one, rather than two.

To demonstrate this problem, and for the other examples in this article, we will use methods from the Parallel class. To begin, create a console application and add the following using directives to the code. NB: If you are using an earlier version of the .NET framework than 4.0, you can create similar examples using standard multi-threading code. (4.0之前的版本没有并行计算功能)

using System.Threading;
using System.Threading.Tasks;

The following code executes a parallel for loop with one million increment operations, each changing the value of a shared variable. The final value of the variable should be one million. However, on a computer with multiple cores or processors, you will likely see a much lower result, caused by the increment operator not being thread-safe.

int total = 0;
Parallel.For(0, 1000000, i =>
{
    total++;
});
Console.WriteLine(total);   // Unlikely to be 1,000,000(结果不会是1,000,000)

 

Interlocked Class

The Interlocked class provides a number of static methods that perform atomic operations. These can generally be regarded as thread-safe. The class is found in the System.Threading namespace.

Increment and Decrement

Two commonly used Interlocked methods are Increment and Decrement. As their names suggest, these methods increase or decrease a variable's value by one, in a similar manner to the increment (++) and decrement (--) operators. Both methods work with either a 32-bit or 64-bit integer, which is passed to the method using a reference parameter.

The code below shows a thread-safe version of the earlier example. In this parallel loop the million operations produce the correct result.

int total = 0;
Parallel.For(0, 1000000, i =>
{
    Interlocked.Increment(ref total);
});
Console.WriteLine(total);   // 1,000,000

Add

The Add method was introduced with the .NET framework version 2.0. It performs an atomic, thread-safe addition of two values. The first parameter accepts a 32-bit or 64-bit integer variable, passed by reference. The second parameter accepts a second integer, which will be added to the first.

The sample below shows the Add method being used successfully within a parallel loop.

int total = 0;
Parallel.For(0, 1000000, i =>
{
    Interlocked.Add(ref total, 5);
});
Console.WriteLine(total);   // 5,000,000

Exchange

The Exchange method originally worked with 32-bit integers, single-precision floating-point numbers or objects. This was extended to a greater choice of data types, including generic types, with .NET 2.0. The method accepts two arguments of the same type. The first, passed by reference, is changed to match that o

抱歉!评论已关闭.