关于线程同步的问题

时间:2009-06-09 16:10:19

标签: multithreading

我对线程情况有疑问。

假设我有3个线程:生产者,帮助者和消费者。 生产者线程处于运行状态(其他两个处于等待状态)并且当它完成时它调用invoke,但问题是它只调用辅助线程而不是消费者,那么它如何确保在它释放资源之后是仅由辅助线程获取,然后由消费者线程获取。

提前致谢

4 个答案:

答案 0 :(得分:2)

或者您是否考虑过,有时候单独的线程比解决方案更容易出问题?

如果确实希望一个线程中的操作与另一个线程中的操作严格序列化,可能更简单的解决方案是丢弃第二个线程并构造代码,以便第一个线程执行按所需顺序进行操作。

这可能并非总是可行,但要记住这一点。

答案 1 :(得分:1)

例如,你可以拥有两个互斥体(或者你正在使用的任何东西):一个用于生产者和助手,另一个用于生产者和消费者

Producer:
  //lock helper
     while true
  {
   //lock consumer
   //do stuff
   //release and invoke helper
   //wait for helper to release
   //lock helper again
   //unlock consumer
   //wait consumer
  }

其他人只是正常锁定和解锁。

另一种可能的方法(可能更好)是为生产者/助手和其他助手/消费者使用互斥量;或者可能在其他两个线程之间分发这个辅助线程任务。你能提供更多细节吗?

答案 2 :(得分:1)

辅助线程实际上只是一个消费者/生产者线程。为帮助程序编写一些代码,就像为任何其他使用者编写生成器的结果一样。一旦完成,就像为任何其他生产者编写帮助程序的一些代码并将其连接到您的消费者线程。

答案 3 :(得分:1)

您可以使用队列来帮助您解决这个问题。 生产者可以处理某些事情,生成它并将其放在帮助程序队列中。 Helper接受它,对它做一些事情,然后将它放在消费者队列中。 消费者接受它,消费它,然后继续。

这样的事情:

Queue<MyDataType> helperQ, consumerQ;
object hqLock = new object();
object cqLock = new object();

// producer thread
private void ProducerThreadFunc()
{
    while(true)
    {
        MyDataType data = ProduceNewData();
        lock(hqLock)
        {
            helperQ.Enqueue(data);
        }
    }
}

// helper thread
private void HelperThreadFunc()
{
    while(true)
    {           
        MyDataType data;
        lock(hqLock)
        {
            data = helperQ.Dequeue();
        }

        data = HelpData(data);
        lock(cqLock)
        {
            consumerQ.Enqueue(data);
        }
    }
}

// consumer thread
private void ConsumerThreadFunc()
{
    while(true)
    {           
        MyDataType data;
        lock(cqLock)
        {
            data = consumerQ.Dequeue();
        }            
        Consume(data);            
    }
}

注意:您需要为此示例添加更多逻辑以确保可用。不要指望它按原样工作。主要是,使用一个线程的信号让另一个线程知道数据在其队列中可用(或者最坏的情况是轮询队列的大小以确保它大于0,如果它是0,那么睡眠 - 但是信号更清洁,更有效率。)

这种方法可以让您以不同的速率处理数据(这可能会导致内存问题)。