Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 关于线程同步的问题_Multithreading - Fatal编程技术网

Multithreading 关于线程同步的问题

Multithreading 关于线程同步的问题,multithreading,Multithreading,我有一个关于线程情况的问题 假设我有3个线程:producer、helper和consumer。 生产者线程处于运行状态(另外两个处于等待状态),当它完成时调用invoke,但问题是它必须只调用helper线程而不是consumer,那么它如何确保在它释放后资源只由helper线程获取,然后由consumer线程获取 提前感谢例如,您可以有两个互斥锁(或您正在使用的任何互斥锁):一个用于生产者和助手,另一个用于生产者和消费者 Producer: //lock helper whil

我有一个关于线程情况的问题

假设我有3个线程:producer、helper和consumer。 生产者线程处于运行状态(另外两个处于等待状态),当它完成时调用invoke,但问题是它必须只调用helper线程而不是consumer,那么它如何确保在它释放后资源只由helper线程获取,然后由consumer线程获取


提前感谢

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

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
  }
其他的只是正常地锁定和解锁


另一种可能的方法(可能更好)是为生产者/助手和其他助手/消费者使用互斥锁;或者,也可以在其他两个线程之间分配此助手线程任务。您可以提供更多详细信息吗?

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

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
  }
其他的只是正常地锁定和解锁


另一种可能的方法(可能更好)是为生产者/助手和其他助手/消费者使用互斥锁;或者,也可以在其他两个线程之间分配此助手线程任务。您能提供更多详细信息吗?

助手线程实际上只是消费者/生产者线程本身。为助手编写一些代码,就像您为任何其他消费者编写代码以获取生产者的结果一样。完成后,为助手编写一些代码,就像为任何其他生产者编写代码一样,并将其连接到消费者线程。

助手线程实际上只是消费者/生产者线程本身。为助手编写一些代码,就像您为任何其他消费者编写代码以获取生产者的结果一样。完成后,为助手编写一些代码,就像为任何其他制作人编写代码一样,并将其连接到用户线程。

或者您是否考虑过,有时使用单独的线程更像是一个问题而不是一个解决方案

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


这可能并不总是可能的,但需要记住。

或者您是否考虑过,有时使用单独的线程更像是一个问题而不是解决方案

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


这可能并不总是可能的,但需要记住。

您可以使用队列来帮助您完成这项任务,并在队列周围设置锁。 Producer处理某个对象,生成该对象,并将其放在助手队列中。 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);            
    }
}
Queue helperQ、consumerQ;
对象hqLock=新对象();
对象cqLock=新对象();
//生产者线程
私有void ProducerThreadFunc()
{
while(true)
{
MyDataType data=ProduceNewData();
锁(hqLock)
{
helperQ.Enqueue(数据);
}
}
}
//辅助线
私有void HelperThreadFunc()
{
while(true)
{           
MyDataType数据;
锁(hqLock)
{
data=helperQ.Dequeue();
}
数据=帮助数据(数据);
锁(cqLock)
{
消费者排队(数据);
}
}
}
//消费线程
私有void ConsumerThreadFunc()
{
while(true)
{           
MyDataType数据;
锁(cqLock)
{
data=consumerQ.Dequeue();
}            
消费(数据);
}
}
注意:您需要为这个示例添加更多的逻辑以确保可用性。不要指望它能按原样工作。主要是,使用一个线程的信号让另一个线程知道其队列中有可用的数据(或者最坏的情况是轮询队列大小以确保其大于0,如果为0,则休眠,但信号更干净、更有效)


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

您可以使用队列来帮助您完成这项任务,并在队列周围设置锁。 Producer处理某个对象,生成该对象,并将其放在助手队列中。 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);            
    }
}
Queue helperQ、consumerQ;
对象hqLock=新对象();
对象cqLock=新对象();
//生产者线程
私有void ProducerThreadFunc()
{
while(true)
{
MyDataType data=ProduceNewData();
锁(hqLock)
{
helperQ.Enqueue(数据);
}
}
}
//辅助线
私有void HelperThreadFunc()
{
while(true)
{           
MyDataType数据;
锁(hqLock)
{
data=helperQ.Dequeue();
}
数据=帮助数据(数据);
锁(cqLock)
{
消费者排队(数据);
}
}
}
//消费线程
私有void ConsumerThreadFunc()
{
while(true)
{           
MyDataType数据;
锁(cqLock)
{
data=consumerQ.Dequeue();
}            
消费(数据);
}
}
注意:您需要为这个示例添加更多的逻辑以确保可用性。不要指望它能按原样工作。主要是,使用一个线程的信号让另一个线程知道其队列中有可用的数据(或者最坏的情况是轮询队列大小以确保其大于0,如果为0,则休眠,但信号更干净、更有效)

这是批准