lol*_*dez 5 c# multithreading locking multicore multiprocessing
我有一个C#程序,它有一个列表,可以在不同的线程中进行写入和读取.写入是用户启动的,可以在任何随机时间点更改数据.读取以恒定循环运行.无论读取是否在任何给定的循环中丢失数据都无关紧要,只要它接收的数据有效并且在未来的循环中得到新数据.
考虑到ConcurrentBag之后,我出于各种原因决定使用锁(简单就是其中之一).在实现锁之后,一位同事向我提到,使用临时引用指向内存中的旧List也可以正常工作,但我担心如果新的赋值和引用赋值同时发生会发生什么.
问:下面的临时参考示例是否安全?
更新:用户输入提供DoStuff()中使用的字符串列表.您可以将这些字符串视为常量的定义,因此需要为将来的循环保留字符串.它们不会在DoStuff()中删除,只能读取.UserInputHandler是唯一一个将更改此列表的线程,DoStuff()是唯一将从此列表中读取的线程.没有其他任何东西可以访问它.
另外,我知道Concurrent命名空间并且已经在其他项目中使用了大部分集合,但是,我选择不在这里使用它们,因为它们添加了额外的代码复杂性(即ConcurrentBag没有简单Clear()函数等).在这种情况下,一个简单的锁就足够了.问题只是下面的第二个例子是否是线程安全的.
锁
static List<string> constants = new List<string>();
//Thread A
public void UserInputHandler(List<string> userProvidedConstants)
{
lock(items)
{
items.Clear();
foreach(var constant in userProvidedConstants)
{
constants.Add(constant);
}
}
}
//Thread B
public void DoStuff()
{
lock(items)
{
//Do read only actions with items here
foreach(var constant in constants)
{
//readonly actions
}
}
}
Run Code Online (Sandbox Code Playgroud)
参考
static List<string> constants = new List<string>();
//Thread A
public void UserInputHandler(List<string> userProvidedConstants)
{
lock(items)
{
items = new List<string>();
foreach(var constant in userProvidedConstants)
{
constants.Add(constant);
}
}
}
//Thread B
public void DoStuff()
{
var constantsReference = constants;
//Do read only actions with constantsReference here
foreach(var constant in constantsReference)
{
//readonly actions
}
}
Run Code Online (Sandbox Code Playgroud)
没有锁,这是不安全的.在此上下文中,复制对列表的引用并没有真正为您做任何事情.当你迭代时,你正在迭代的列表仍然很可能在另一个线程中被变异,从而导致各种可能的错误.
| 归档时间: |
|
| 查看次数: |
280 次 |
| 最近记录: |