Parallel.Foreach 如何在不同的线程中创建局部变量


 Parallel.ForEach(array_ptr, 
                new ParallelOptions { MaxDegreeOfParallelism = 2 },                     
                (current_ptr, state, index) => after_di(current_ptr)    
            );

函数after_di:

private IntPtr after_di(IntPtr in_ptr)
    {
        IntPtr det_ptr = det(in_ptr);
        free_image_pointer(in_ptr);
        IntPtr adp_ptr = adaptive_scaler(det_ptr, 1280, 720, 1, 1, 70);
        free_image_pointer(det_ptr);
        IntPtr cmu_ptr = cmu(adp_ptr, 1, 1, 1, 1, 1, 1, 1, 1);
        free_image_pointer(adp_ptr);
        return cmu_ptr;
    }

问题是当并行在同一线程中运行时,free_image_pointer函数(在 dll C 代码中释放内存(不会释放正确的指针,因此会导致错误。我希望每个 IntPtr det_ptr、IntPtr adp_ptr、IntPtr cmu_ptr在每个项目循环上都不同。可能吗?

更新测试:调试时,我看到问题只发生在 det(( 函数上。所以我只用 det(( 函数做了一些测试。在我的主要函数中,这就是我所做的:

  IntPtr main_out0_ptr = det(temp_rgb0);
  IntPtr main_out1_ptr = det(temp_rgb1);

上面的代码很好。但是,如果我像这样在每个功能上创建新线程:

Thread th1 = new Thread(() =>  det(temp_rgb0));
th1.Start();
Thread th2 = new Thread(() => det(temp_rgb1));
th2.Start();

发生错误,它说:试图读取或写入受保护的内存。这通常表示其他内存已损坏。

我仍然不知道为什么会这样。

如果不查看det(),adaptive_scaler()的实现,很难提出建议......但ThreadLocal<T>是为这样的场景而设计的(其中每个线程都需要有一个值的本地副本。

下面是 MSDN 链接,还有一个演示其工作原理的代码示例。

最新更新