并行。foreach循环不起作用。

发布于 2025-02-08 10:55:27 字数 1370 浏览 2 评论 0原文

我有两种可以为我完成工作的方法,一种是串行的,另一种是平行的。 并行化的原因是因为有很多迭代(大约100,000左右) 由于某种原因,平行的人会跳过或双重进行一些迭代,我不知道如何调试它。

串行方法

for(int i = somenum; i >= 0; i-- ){

    foreach (var nue in nuelist)
    {
        foreach (var path in nue.pathlist)
        {
            foreach (var conn in nue.connlist)
            {
                Func(conn,path); 
            }
        }
    }
}

并行方法

for(int i = somenum; i >= 0; i-- ){

    Parallel.ForEach(nuelist,nue =>
    {
        Parallel.ForEach(nue.pathlist,path=>
        {
            Parallel.ForEach(nue.connlist, conn=>
            {
                Func(conn,path);
            });
        });
    });
}

在路径类中的

Nue firstnue;
public void Func(Conn conn,Path path)
{
    List<Conn> list = new(){conn};
    list.AddRange(path.list);
    _ = new Path(list); 
}
public Path(List<Conn>)
{
   //other things
   firstnue.pathlist.Add(this);
   /*
   firstnue is another nue that will be 
   in the next iteration of for loop
   */
}

它们都是相同的方法,当然,foreachParallel.Foreach循环。

该代码适用于在这里(github)(github)页)

I have 2 methods that can do the work for me, one is serial and the other one is parallel.
The reason for parallelization is because there are lots of iteration(about 100,000 or so)
For some reason, the parallel one do skip or double doing some iterations, and I don't have any clue how to debug it.

The serial method

for(int i = somenum; i >= 0; i-- ){

    foreach (var nue in nuelist)
    {
        foreach (var path in nue.pathlist)
        {
            foreach (var conn in nue.connlist)
            {
                Func(conn,path); 
            }
        }
    }
}

The parallel method

for(int i = somenum; i >= 0; i-- ){

    Parallel.ForEach(nuelist,nue =>
    {
        Parallel.ForEach(nue.pathlist,path=>
        {
            Parallel.ForEach(nue.connlist, conn=>
            {
                Func(conn,path);
            });
        });
    });
}

Inside Path class

Nue firstnue;
public void Func(Conn conn,Path path)
{
    List<Conn> list = new(){conn};
    list.AddRange(path.list);
    _ = new Path(list); 
}
public Path(List<Conn>)
{
   //other things
   firstnue.pathlist.Add(this);
   /*
   firstnue is another nue that will be 
   in the next iteration of for loop
   */
}

They are both the same method except, of course, foreach and Parallel.ForEach loop.

the code is for the code in here (GitHub page)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好倦 2025-02-15 10:55:27

list&lt; t&gt;,我认为您与firstNue.pathlist一起使用,不是线程安全。这意味着,当您从相同的列表中添加/删除项目同时从多个线程中添加/lt; t&gt;时,您的数据将损坏。为了避免这个问题,最简单的解决方案是使用锁定,因此多个线程不会一次尝试一次修改列表。

但是,一个锁可以实质上序列列表操作,如果您在func中唯一要做的就是更改列表,则您可能不会通过并行化代码来获得太多收益。但是,如果您仍然想尝试一下,您只需要更改以下内容:

firstnue.pathlist.Add(this);

对此:

lock (firstnue.pathlist)
{
  firstnue.pathlist.Add(this);
}

List<T>, which I assume you use with firstnue.pathlist, isn't thread-safe. That means, when you add/remove items from the same List<T> from multiple threads at the same time, your data will get corrupt. In order to avoid that problem, the simplest solution is to use a lock, so multiple threads doesn't try to modify list at once.

However, a lock essentially serializes the list operations, and if the only thing you do in Func is to change a list, you may not gain much by parallelizing the code. But, if you still want to give it a try, you just need to change this:

firstnue.pathlist.Add(this);

to this:

lock (firstnue.pathlist)
{
  firstnue.pathlist.Add(this);
}
霓裳挽歌倾城醉 2025-02-15 10:55:27

感谢 sedat-kapanoglu ,我发现问题确实与线程安全有关。解决方案是将每个列表&lt; t&gt;更改为concurrentbag&lt; t&gt;

对于像我一样的每个人,“平行不使用收藏”的解决方案是从system.collections.generic更改为system.collections.collections.concurrent

Thanks to sedat-kapanoglu, I found the problem is really about thread safety. The solution was to change every List<T> to ConcurrentBag<T>.

For everyone, like me, The solution of "parallel not working with collections" is to change from System.Collections.Generic to System.Collections.Concurrent

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文