关于线程安全,只有一个线程写... [英] About thread safety where only one thread writes...

查看:99
本文介绍了关于线程安全,只有一个线程写...的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我想我知道......问题是我可能错了。



一般情况下,如果保证变量只能被写入一个线程,其他人可以毫无问题地阅读。正确吗?



更具体地说,我可以使用ConcurrentDictionary,但不认为有必要。这个想法是Windows窗体将启动一个带轮询操作的线程。线程将保持表单响应。

我希望表单显示在轮询操作中找到的作业数。

我打算创建一个字典< string ,串>在表格中有一些条目,例如:

继续,真实和工作,0

如果点击表格上的停止按钮,字典中continue的值将设置为false。线程中的while循环将读取并知道停止。在此之前,每次轮询时,它会将字典中jobs的值更改为表示轮询数的字符串(不是真的,但这是一个非常简单的例子)。现在返回Windows窗体,计时器将运行,它将读取字典中的作业值并显示它。



重点是只有一个线程将更新KeyValuePair的值< string,>在字典里。另一个线程会读取它,但只有一个线程会写入该对。这样做会安全吗?如果值正确则无关紧要。这将是下一次循环/事件发生。



现在我认为答案是这样做是安全的,但如果没有,那么发送怎么样一个字符串,即两个字符串。如果在线程启动后只有一个线程要写入该字符串,那么线程读取它或何时读取是否重要?



我甚至可以使用Interlocked。 Increment(),但问题是,如果只有一个线程写入,那么正常变量是否可以安全起诉。



所有线程描述似乎都是复杂的的情况。这很简单。



谢谢,Mike

OK, I think I know... the problem is I might be wrong.

In general, if a variable is guaranteed to be written to by only one thread, it can be read by others with no problem. Correct?

More specifically, I could use a ConcurrentDictionary, but don't think it is necessary. The idea is that a Windows Form will start a thread with a polling operation. The thread will be to keep the form responsive.
I want the Form to display the number of jobs found in the polling operation.
I plan to create a dictionary<string,string> in the Form with a few entries, say:
"continue","true" and "jobs", "0"
If a Stop button on the Form is clicked, the value of "continue" in the dictionary will be set to "false". The while loop in the thread will read that and know to stop. Before that though, each time it polls, it will change the value of "jobs" in the dictionary to a string representing the number of polls (not really, but that is a real simple example). Now back in the Windows Form, a timer will be running and it will be reading that "jobs" value in the dictionary and displaying it.

The point is that only one thread will ever update the value of a KeyValuePair<string,> in the dictionary. The other thread will read it, but only one thread will ever write to that pair. Is that going to be safe to do? It doesn't even matter if the value is correct. It will be the next time the loop/event occurs.

Now I think the answer is that it is safe to do that, but if not, how about just sending a string, that is two strings. If only one thread is ever going to write to that string after the thread starts, does it matter what thread reads it or when?

I could even use an Interlocked.Increment(), but the question is whether a normal variable is safe to sue if only one thread ever writes to it.

All descriptions of threading seem to be about complicated situations. This is just simple.

Thanks, Mike

推荐答案

如果一个线程从字典读取,并且另一个写入字典,这个字典必须是线程安全的。但是你可以使用一个非线程安全的集合,因为你可以将两个操作(或从同一个集合对象的不同线程访问的所有其他操作)夹在 lock 中语句使用相同的锁对象。最好不要使用可访问的对象(例如集合或托管它的任何对象)作为锁定对象,以防止直接使用它。为了防止这种情况,这个对象应该是私有的,不能被调用代码访问。



从理论上讲,这不是一个严格要求的规则,只是一个简单的可靠的模式。您总是可以创建更宽松的同步规则,有时可以提高一些平均吞吐量。例如,您可以设计一个以互斥方式授予对集合元素的访问权限的模式,但是您可以对元素对象进行操作,这两个元素不同时可以并行完成。如果元素是引用类型对象,则特别容易。



不同线程使用字典的整个想法可能是被认为有问题。更典型地,使用阻塞集合。例如,我看不出它如何有助于保持应用程序的响应;通常的方法是控制调度程序调用 BeginInvoke ,仅使用通过UI线程调用传递的数据访问UI中的数据。还记得:最好的同步是没有同步的。也许你改进了你的应用程序线程设计。



不要误会我的意思:我不是说你不应该这样做;为了获得更多的建议,需要更详细地了解你想要达到的目标。



-SA
If one thread reads from a dictionary, and another writes to dictionary, this dictionary is required to be thread-safe. But you can use a collection which is not thread-safe, because you can sandwich both operations (or all other operations accessed from different threads of the same collection object) in a lock statement using the same lock object. It's better not to use an accessible object (such as collection, or any object hosting it) as a lock object, to prevent using it directly. To protect from such cases, this object should be private, not accessible by the calling code.

Theoretically speaking, this is not a strictly required rule, just one simple and reliable pattern. You can always invent more relaxed synchronization rule which sometime could improve some average throughput. For example, you can design a schema that grants access to a collection element in a mutually exclusive manner, but you can have the operations on an element object which are done in parallel when two elements are different. It is especially easy to do if the elements are reference-type objects.

The whole idea to use a dictionary by different thread might be considered questionable. More typically, blocking collections are used. For example, I cannot see how it helps to keep the application responsive; the usual approach is to Control's or Dispatcher's Invoke or BeginInvoke, accessing no data in the UI, using only the data passed through UI thread invocation. Also remember: best synchronization is no synchronization. Maybe you improve your application threading design.

Don't get me wrong: I'm not saying you should not do it; for more certain advice, more detailed understanding of what you are trying to achieve would be required.

—SA


这篇关于关于线程安全,只有一个线程写...的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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