简体   繁体   English

c#2.0 int32线程安全吗?

[英]c# 2.0 Is int32 threadsafe?

I want to increment an integer that gets incremented in a timer event handler and read by the main and other worker threads ie one writer thread and multiple reader threads. 我想增加一个在计时器事件处理程序中递增的整数,并由主线程和其他工作线程(即一个写线程和多个读线程)读取。 will it be threadsafe? 它是线程安全的吗?

I have a timer in my application that runs every 5 seconds 我的应用程序中有一个计时器,每5秒运行一次

MyClock = new System.Threading.Timer( new TimerCallback(this.Ticker), null, Timeout.Infinite, Timeout.Infinite ); MyClock = new System.Threading.Timer(new TimerCallback(this.Ticker),null,Timeout.Infinite,Timeout.Infinite);复制代码

that I turn on like this MyClock.Change( 5000, 5000 ); 我像这样打开MyClock.Change(5000,5000);

If I increment an integer in the Ticker handler like this tickerCounter++; 如果我像这样的tickerCounter ++在Ticker处理程序中增加一个整数;

Can I then do a read-only access from main thread or worker threads of the same application? 然后可以从同一应用程序的主线程或工作线程进行只读访问吗? Will it be thread safe? 它是线程安全的吗? Is there any chance of the reader to read a partial value? 读者有机会阅读部分价值吗? or causing a threading exception? 或导致线程异常?

Firstly: read Eric Lippert's blog post: What is this thing you call "thread-safe"? 首先:请阅读Eric Lippert的博客文章: 您称之为“线程安全”的东西是什么? It will change how you think about thread safety, and how you ask similar questions in the future. 它将改变您对线程安全性的看法,以及将来如何问类似的问题。

The reads will be atomic - you'll never see "half" an update - but you won't necessarily see the latest value. 读取将是原子的 -您将永远不会看到“一半”的更新-但您不一定会看到最新的值。 (That means that the next increment may see an "old" (lower) value to increment, of course.) (当然,这意味着下一个增量可能会看到一个“旧”(较低)值要递增。)

Additionally, the increment itself isn't inherently safe - if there were several threads incrementing at the same time, they could all read the same value, then increment locally, then write the new value - so the result could be an increment of 1, even if 10 threads were incrementing. 此外,增量本身并不是天生的安全-如果有多个线程同时进行增量,则它们都可以读取相同的值,然后在本地进行增量,然后写入新值-因此结果可能为1,即使增加10个线程。

You should consider using Interlocked.Increment to perform the increment. 您应该考虑使用Interlocked.Increment执行增量。 If you also make the variable volatile, I believe you should be safe just to read it directly when you only want to read it. 如果你使变量波动,我相信你应该是安全的只是直接读取它,当你只想读它。

Perhaps you could use Interlocked.Increment(ref Int32) to do the incrementing? 也许您可以使用Interlocked.Increment(ref Int32)进行增量? That does it as an atomic operation. 这样做是原子操作。

Incrementing like this 像这样递增

tickerCounter++;

in multiple threads, without locking, is not threadsafe. 在多线程中,如果没有锁定,则不是线程安全的。 You can use the Interlocked class to perform lock-free, threadsafe incrementing. 您可以使用Interlocked类执行无锁,线程安全的增量。

If only a single thread is modifying the value, with many threads reading the value, then tickerCounter++ is threadsafe in the sense that no thread will ever suffer a partial read. 如果只有一个线程正在修改该值,而有多个线程正在读取该值,则tickerCounter++在某种意义上是线程安全的,因为没有线程会遭受部分读取。 Of course there is still a race condition, but even if you use Interlocked , there would be a race. 当然,仍然存在比赛条件,但是即使您使用Interlocked也会发生比赛。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM