【问题标题】:lock shared data using c#使用 c# 锁定共享数据
【发布时间】:2010-04-27 14:05:19
【问题描述】:

我有一个程序 (C#),其中包含要执行的测试列表。
另外,我有两个线程。一种用于将任务添加到列表中,另一种用于读取并从中删除已执行的任务。
每次其中一个线程想要访问列表时,我都会使用“锁定”功能。
我想做的另一件事是,如果列表为空,则需要从列表中读取的线程将休眠。并在第一个线程将任务添加到列表时唤醒。 这是我写的代码:

...
List<String> myList = new List();
Thread writeThread, readThread;
writeThread = new Thread(write);
writeThread.Start();
readThraed = new Thread(read);
readThread.Start();
...
private void write()
{
   while(...)
   {
     ...
     lock(myList)
     {
        myList.Add(...);
     }
     ...
     if (!readThread.IsAlive)
     {
        readThraed = new Thread(read);
        readThread.Start();
     }
     ...
   }
   ...
}

private void read()
{
bool noMoreTasks = false;
   while (!noMoreTasks)
   {
      lock (MyList)//syncronize with the ADD func.
      {
                if (dataFromClientList.Count > 0)
                {
                    String task = myList.First();
                    myList.Remove(task);
                }
                else
                {
                    noMoreTasks = true;
                }      
      }
      ...
   }
   readThread.Abort();
}

显然我做错了,它没有按预期执行(readTread 没有从列表中读取)。
有谁知道我的问题是什么,以及如何解决?
非常感谢,

【问题讨论】:

    标签: c# multithreading locking


    【解决方案1】:

    您需要的是一个阻塞队列。它就像一个普通的队列,除了 Dequeue 方法会阻塞,如果没有任何队列。 Here 是一种实现方式。一旦你实现了阻塞队列,那么其他一切都很容易。请注意您使用的阻塞队列的实现。我已经看到了很多存在微妙线程问题的示例。最好坚持我提供的链接。

    public class Example
    {
      private BlockingQueue<Task> m_Queue = new BlockingQueue<Task>();
    
      public void StartExample()
      {
        Thread producer = new Thread(() => Producer());
        Thread consumer = new Thread(() => Consumer());
        producer.Start();
        consumer.Start();
        producer.Join();
        consumer.Join();
      }
    
      private void Producer()
      {
        for (int i = 0; i < 10; i++)
        {
          m_Queue.Enqueue(new Task());
        }
      }
    
      private void Consumer()
      {
        while (true)
        {
          Task task = m_Queue.Dequeue();
        }
      }
    }
    

    【讨论】:

    • 感谢您的快速回答,我想试试您的回答,但我没有 BlockingQueue 类。我需要添加一些使用吗?
    • 深吸一口气,再读一遍答案;这次慢慢来。 Brian 在他的回答中提供了 BlockingQueue 类实现的链接。
    • .NET 4.0 中包含一个 BlockingQueue 实现。
    【解决方案2】:

    我建议你看看 Jon Skeet 的 Producer Consumer example。 有关生产者消费者的更多信息,请查看Wikipedia

    【讨论】:

      猜你喜欢
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 2013-09-01
      相关资源
      最近更新 更多