多线程单生产者多个消费者实施

时间:2012-03-01 06:42:05

标签: c# multithreading queue producer-consumer

我想用单个生产者和多个消费者的模式实现多文件下载。

我拥有的: - 找到要在循环中下载的新链接的代码 - 找到新链接时 - 它会调用下载功能 - 下载功能接受源文件路径和目标文件路径并下载文件。

我想做什么 - 我想同时下载X个文件(我不知道文件总数) - 在任何时候我都应该能够同时下载X文件 - 一旦X文件中的一个完成下载 - 调用函数应该能够立即添加新的下载 - 反过来立即下载

  • 所以我有一个生产者功能,不断添加新的下载到队列(在任何时候最大X下载)
  • 多个X线程,它消耗下载并单独开始下载。一旦完成下载 - 生产者应该能够添加新的下载 - 这将产生新的线程。

非常感谢示例

4 个答案:

答案 0 :(得分:5)

对于此P / C问题,您只需BlockingCollection<T>

//shared and thread-safe
static BlockingCollection<string> queue = new BlockingCollection<string>(100);

// Producer
queue.Add(fileName);  // will block when full

// Consumer
if (queue.TryTake(out fileName, timeOut))  // waits when empty
  ...

你会想要通过超时和CancellationTokens进行微调。

答案 1 :(得分:2)

ReaderWriterLockSlim课程旨在实现这一目标。

另外,请查看这个关于线程的精彩网站:

http://www.albahari.com/threading/part4.aspx#_Reader_Writer_Locks

该示例来自上述网站。

class SlimDemo
{
  static ReaderWriterLockSlim _rw = new ReaderWriterLockSlim();
  static List<int> _items = new List<int>();
  static Random _rand = new Random();

  static void Main()
  {
    new Thread (Read).Start();
    new Thread (Read).Start();
    new Thread (Read).Start();

    new Thread (Write).Start ("A");
    new Thread (Write).Start ("B");
  }

  static void Read()
  {
    while (true)
    {
      _rw.EnterReadLock();
      foreach (int i in _items) Thread.Sleep (10);
      _rw.ExitReadLock();
    }
  }

  static void Write (object threadID)
  {
    while (true)
    {
      int newNumber = GetRandNum (100);
      _rw.EnterWriteLock();
      _items.Add (newNumber);
      _rw.ExitWriteLock();
      Console.WriteLine ("Thread " + threadID + " added " + newNumber);
      Thread.Sleep (100);
    }
  }

  static int GetRandNum (int max) { lock (_rand) return _rand.Next(max); }
}

答案 2 :(得分:1)

使用Concurrent集合进行老板与其工作人员之间的沟通 ConcurrentQueue(如果您关心订单)或ConcurrentBag 老板添加到ConcurrentQueue(添加方法)并且队员从队列中获取(Take方法)。如果您需要代码,请告诉我。

答案 3 :(得分:0)

我建议调查Task Parallel Library。这非常干净地包装方法调用,并为您管理多个线程。