gpt4 book ai didi

c# - 在独占线程约束下锁定

转载 作者:行者123 更新时间:2023-12-03 12:47:40 24 4
gpt4 key购买 nike

当使用多个线程更新共享数组时,是否有必要锁定此函数?前提是每个数组元素最多只能由 1 个线程访问(读取和写入)。

谢谢。

例如

       public string[] UpdateArray
(List<string> myList, Func<string,string>del)
{
int count = myList.Count;
string[] myArray = new string[count];
Parallel.For(0, count, i => myArray[i] = del(myList[i]));
return myArray;
}

更新:

它的预期用途如下,在 WPF 同步上下文中


public Task<string[]> updateArrayTask()
{
List<string> myList = GetMyList();
Func<string, string> del = MyDel;
var t1=Task<string[]>.Run(() => UpdateArray(myList, del));
return t1;
}

然后在异步函数中等待这个任务。

最佳答案

锁定可能是不必要的,但这种方法迫使您考虑可见性、波动性、内存模型和 all this thorny stuff .当您编写应用程序代码的目的是易于维护并保证在它可能运行的任何 CPU 架构上产生正确的结果时,这是非常不受欢迎的。所以我的建议是使用 PLINQ 来绕过这个问题。而不是 Parallel 类:

public string[] UpdateArray(List<string> myList, Func<string, string> del)
{
return myList
.AsParallel()
.AsOrdered()
.Select(s => del(s))
.ToArray();
}

更新:如果您发现 PLINQ 方法的开销太大,您可以通过添加 Thread.MemoryBarrier 来提高当前方法的稳健性。在最后。从技术上讲,它可能不是必需的,但它可以以非常低的价格让您高枕无忧!

Synchronizes memory access as follows: The processor executing the current thread cannot reorder instructions in such a way that memory accesses prior to the call to MemoryBarrier() execute after memory accesses that follow the call to MemoryBarrier().

要进一步减少并行开销,您可以使用 Partitioner.Create方法,这样您就可以使用列表的大块部分而不是其单个元素。

public string[] UpdateArray(List<string> myList, Func<string, string> del)
{
string[] myArray = new string[myList.Count];
Parallel.ForEach(Partitioner.Create(0, myList.Count), range =>
{
for (int i = range.Item1; i < range.Item2; i++)
{
myArray[i] = del(myList[i]);
}
});
Thread.MemoryBarrier();
return myArray;
}

关于c# - 在独占线程约束下锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62126927/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com