【问题标题】:Share data between threads在线程之间共享数据
【发布时间】:2011-07-31 03:48:02
【问题描述】:

我正在尝试实现一种应该使用线程或任务并行运行的算法。困难在于我希望线程/任务不时与所有其他线程分享它们的最佳结果。

基本思路是这样的:

//Accessible from each thread
IProducerConsumerCollection<MyObject> _bestObjects;

//Executed in each thread
DoSomeWork(int n){
    MyObject localObject;
    for(var i = 0; i < n; i++){
        //Do some calculations and store results in localObject
        if((i/n)%0.5 == 0)
        {
            //store localObject in _bestObjects
            //wait until each thread has stored its result in _bestObjects
            //get the best result from _bestObjects and go on
        } 
    }
}

如何使用 System.Threading 或 System.Threading.Tasks 来实现这一点?任务是否真的不应该用于长时间运行的操作?

更新:澄清

拥有一个线程安全的集合不是我的问题,而是让线程停止,发布结果,等到所有其他线程都发布了他们的结果,然后再继续。所有线程将同时运行。 长话短说:

  1. 对于长时间运行的操作有什么更好的方法?任务或线程或其他什么?
  2. 假设线程数是在运行时设置的(取决于可用的内核),如何在线程/任务之间进行通信以告知每个线程所有其他线程的状态。

最好的问候

【问题讨论】:

  • 可以从阅读Thread-Safe Collections开始
  • 这没有帮助。我非常了解 System.Collections.Concurrent,我已经搜索了 MSDN 和 Google 大约两个小时。问题不是要有一个线程安全的对象来存储我的结果,而是让一个线程/任务在特定条件下停止并等待所有其他线程执行相同操作然后继续。
  • 如果您只需要一个 (?) 线程在某个时间处于活动状态 - 使用 semaphore。或者我无法得到你的问题:-S
  • 见:How to: Synchronize Concurrent Operations with a Barrier。 “Barrier 是一个对象,它可以防止并行操作中的单个任务继续执行,直到所有任务都到达障碍。当并行操作分阶段发生并且每个阶段都需要任务之间的同步时,它很有用。”
  • 太好了!障碍正是我所需要的。

标签: c# .net multithreading task-parallel-library


【解决方案1】:

请看下面的例子。

public class Worker
{
    public SharedData state;
    public void Work(SharedData someData)
    {
        this.state = someData;
        while (true) ;
    }

}

public class SharedData {
    X myX;
    public getX() { ... }
    public setX(anX) { ... }    
}

public class Sharing
{
    public static void Main()
    {
        SharedData data = new SharedDate()
        Worker work1 = new Worker(data);
        Worker work2 = new Worker(data);
        Thread thread = new Thread(new ThreadStart(work1.Work));
        thread.start();
        Thread thread2 = new Thread(new ThreadStart(work2.Work));
        thread2.start();
    }
}

【讨论】:

    【解决方案2】:

    bomslang的回复不准确。无法使用ThreadStart 实例化新线程,传入Work 方法,该方法需要在上面的示例中传递参数。 ParameterizedThreadStart 会更合适。 Main 方法的示例代码看起来更像这样:

    public class Sharing
    {
        public static void Main()
        {
            SharedData data = new SharedDate()
            Worker work1 = new Worker(data);
            Worker work2 = new Worker(data);
            Thread thread = new Thread(new ParameterizedThreadStart(work1.Work));
            thread.start(someData);
            Thread thread2 = new Thread(new ParameterizedThreadStart(work2.Work));
            thread2.start(someData);
        }
    }
    

    请注意,'work' 被传递到 ParameterizedThreadStart 作为新线程执行的方法,传递给 'work' 方法所需的数据正在调用 start 中传递。数据必须作为对象传递,因此工作方法也需要将其转换回适当的数据类型。最后,还有另一种通过使用匿名方法将数据传递到新线程的方法。

    【讨论】:

    • 你能解释一下吗?
    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    相关资源
    最近更新 更多