标签: interlocked-increment

读取由Interlocked在其他线程上更新的int

(这是重复:如何正确读取Interlocked.Increment'ed int字段?但是,在阅读了答案和评论之后,我仍然不确定正确的答案.)

有些代码我不拥有,也无法更改为使用在几个不同线程中增加int计数器(numberOfUpdates)的锁.所有通话都使用:

Interlocked.Increment(ref numberOfUpdates);
Run Code Online (Sandbox Code Playgroud)

我想在我的代码中读取numberOfUpdates.既然这是一个int,我知道它不会撕裂.但是,确保我获得最新价值的最佳方法是什么?看起来我的选择是:

int localNumberOfUpdates = Interlocked.CompareExchange(ref numberOfUpdates, 0, 0);
Run Code Online (Sandbox Code Playgroud)

要么

int localNumberOfUpdates = Thread.VolatileRead(numberOfUpdates);
Run Code Online (Sandbox Code Playgroud)

两者都有效(无论优化,重新排序,缓存等,都可以提供最新的价值)?一个比另一个更受欢迎吗?还有第三种选择更好吗?

.net c# multithreading interlocked interlocked-increment

35
推荐指数
3
解决办法
1万
查看次数

Interlocked.Increment的性能

Interlocked.Increment(ref x)不是更快或更慢x++的在各种平台上整数和长?

.net performance interlocked interlocked-increment

22
推荐指数
4
解决办法
1万
查看次数

Interlocked.CompareExchange <Int>使用GreaterThan或LessThan而不是相等

System.Threading.Interlocked对象允许加法(减法)和比较作为原子操作.似乎只是不做相等的CompareExchange以及作为原子比较的GreaterThan/LessThan将是非常有价值的.

Interlocked.GreaterThanIL 的假设特征还是CPU级功能?都?

缺少任何其他选项,是否可以用C++或直接IL代码创建这样的功能并将该功能公开给C#?

c# c++ il interlocked interlocked-increment

22
推荐指数
3
解决办法
7463
查看次数

C#多线程无符号增量

我想从多个线程递增无符号整数.

我知道Interlocked.Increment,但它不处理无符号整数.我可以使用lock(),但出于性能原因我不愿意.

它只是以正常方式增加它的线程安全吗?如果偶尔的增量丢失也没关系,因为它只用于统计.我不想要的是腐败的价值.

c# multithreading unsigned interlocked-increment

15
推荐指数
2
解决办法
9239
查看次数

在#ach循环中,C#++运算符是否成为线程安全的?

最近我从VB转到C#,所以我经常使用C#到VB.NET转换器来理解语法差异.在将下一个方法移动到VB时,我发现了一个有趣的事情

C#原始代码:

 public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
{
   int trueCnt = 0;
   foreach(bool b in bools)
      if (b && (++trueCnt > threshold)) 
          return true;
   return false;          
} 
Run Code Online (Sandbox Code Playgroud)

VB.NET结果:

Public Function ExceedsThreshold(threshold As Integer, bools As IEnumerable(Of Boolean)) As Boolean
Dim trueCnt As Integer = 0
For Each b As Boolean In bools
    If b AndAlso (System.Threading.Interlocked.Increment(trueCnt) > threshold) Then
        Return True
    End If
Next
Return False End Function
Run Code Online (Sandbox Code Playgroud)

C#的++运算符被替换为System.Threading.Interlocked.Increment 是否意味着++如果在foreach循环中使用,线程安全运算符不会成为线程安全的?它是一种语法糖吗?如果这是真的,那么为什么转换器放在Interlocked.IncrementVB版本中?我认为C#和VB中的foreach完全相同.或者它只是一个转换器"保险"?

c# foreach increment thread-safety interlocked-increment

11
推荐指数
1
解决办法
534
查看次数

32位环境下64位变量的原子增量

另一个问题的答案出现了一些有趣的事情,现在我无法理解Interlocked.Increment(ref long value)32位系统是如何工作的.让我解释.

InterlockedIncrement64在编译32位环境时,Native 现在不可用了,好吧,这是有道理的,因为在.NET中你不能根据需要对齐内存,可以从托管调用然后删除它.

在.NET我们可以调用Interlocked.Increment()与对64位的变量的引用,我们仍然没有关于其对齐的任何约束(例如,在一个结构中,也在这里我们可以使用FieldOffsetStructLayout),但文献中没有提到任何限制(AFAIK ).这很神奇,它有效!

Hans Passant注意到这Interlocked.Increment()是JIT编译器识别的一种特殊方法,它将发出对 COMInterlocked :: ExchangeAdd64()的调用,然后调用FastInterlockExchangeAddLong,它是InterlockedExchangeAdd64的一个宏,它具有InterlockedIncrement64的相同限制.

现在我很困惑.

忘记一秒钟的托管环境,然后回归原生.为什么InterlockedIncrement64不能工作InterlockedExchangeAdd64呢?InterlockedIncrement64是一个宏,如果内在函数不可用,InterlockedExchangeAdd64那么它可以实现为InterlockedExchangeAdd64... 的调用

让我们回到托管:如何在32位系统上实现原子64位增量?我认为句子"这个函数对于调用其他互锁函数是原子的"很重要,但我仍然没有看到任何代码(感谢Hans指出更深入的实现)来做到这一点.InterlockedExchangedAdd64当内在函数不可用时,让我们从WinBase.h中选择实现:

FORCEINLINE
LONGLONG
InterlockedExchangeAdd64(
    _Inout_ LONGLONG volatile *Addend,
    _In_    LONGLONG Value
    )
{
    LONGLONG Old;

    do {
        Old = *Addend;
    } while (InterlockedCompareExchange64(Addend, …
Run Code Online (Sandbox Code Playgroud)

.net c# interlocked-increment

11
推荐指数
1
解决办法
848
查看次数

使用'不安全'线程函数是否安全?

请原谅我略带幽默的头衔.我在其中使用了两个不同的"安全"一词(显然).

我对线程很陌生(好吧,我已经使用了多年的线程,但只有非常简单的形式).现在我面临着编写某些算法的parallal实现的挑战,并且线程需要处理相同的数据.考虑以下新手错误:

const
  N = 2;

var
  value: integer = 0;    

function ThreadFunc(Parameter: Pointer): integer;
var
  i: Integer;
begin
  for i := 1 to 10000000 do
    inc(value);
  result := 0;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  threads: array[0..N - 1] of THandle;
  i: Integer;
  dummy: cardinal;
begin

  for i := 0 to N - 1 do
    threads[i] := BeginThread(nil, 0, @ThreadFunc, nil, 0, dummy);

  if WaitForMultipleObjects(N, @threads[0], true, INFINITE) = WAIT_FAILED then
    RaiseLastOSError;

  ShowMessage(IntToStr(value));

end;
Run Code Online (Sandbox Code Playgroud)

初学者可能希望上面的代码显示消息20000000.实际上,首先value是等于0 …

delphi multithreading thread-safety critical-section interlocked-increment

8
推荐指数
1
解决办法
310
查看次数

Interlocked.Increment和递增值的返回

我们有一个方法可以维护应用程序中所有事件的全局序列索引.因为它是网站,所以预计这种方法线程安全.线程安全实现如下:

private static long lastUsedIndex = -1;

public static long GetNextIndex()
{
    Interlocked.Increment(ref lastUsedIndex);
    return lastUsedIndex;
}
Run Code Online (Sandbox Code Playgroud)

但是我们注意到在一些不重负载的情况下,系统中出现了重复索引.简单测试显示,对于100000次迭代,大约有1500个重复项.

internal class Program
{
    private static void Main(string[] args)
    {
        TestInterlockedIncrement.Run();
    }
}

internal class TestInterlockedIncrement
{
    private static long lastUsedIndex = -1;

    public static long GetNextIndex()
    {
        Interlocked.Increment(ref lastUsedIndex);
        return lastUsedIndex;
    }

    public static void Run()
    {
        var indexes = Enumerable
            .Range(0, 100000)
            .AsParallel()
            .WithDegreeOfParallelism(32)
            .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
            .Select(_ => GetNextIndex())
            .ToList();

        Console.WriteLine($"Total values: {indexes.Count}");
        Console.WriteLine($"Duplicate values: {indexes.GroupBy(i => i).Count(g => g.Count() > …
Run Code Online (Sandbox Code Playgroud)

.net multithreading increment interlocked-increment

5
推荐指数
1
解决办法
1180
查看次数

互锁变量访问和关键部分互锁增量之间的差异

有人可以帮助解释c ++中互锁变量访问和关键部分互锁增量之间的差异吗?非常感谢,提前谢谢.

c++ winapi critical-section interlocked-increment

4
推荐指数
1
解决办法
3078
查看次数

我可以使用互锁操作来更新多个值以避免锁定关键部分/互斥锁吗?

我有一个多线程应用程序(C++),我需要增加/更改一系列值.如果我使用一系列互锁操作,它们被认为是单个原子操作吗?就像在这个例子中:

InterlockedIncrement(&value1);
InterlockedIncrement(&value2);
InterlockedExchange(&oldValue, newValue);
Run Code Online (Sandbox Code Playgroud)

或者我们更好地锁定以执行同步?像这样:

EnterCriticalSection(&cs);
value1++;
value2++;
oldValue = newValue;
LeaveCriticalSection(&cs);
Run Code Online (Sandbox Code Playgroud)

我认为需要一个锁定,但我不确定......所有的值要么处于旧状态,要么处于新状态,这一点非常重要.

c++ multithreading synchronization interlocked-increment

3
推荐指数
1
解决办法
451
查看次数