C+中的多线程实现+; 我是一个初学者,在C++中使用多线程,所以如果你能给我一些建议,我会很感激。

C+中的多线程实现+; 我是一个初学者,在C++中使用多线程,所以如果你能给我一些建议,我会很感激。,c++,multithreading,C++,Multithreading,我有一个函数,它从视频流中接收前一帧和当前帧(让我们调用此函数,readFrames())。该函数的任务是计算运动估计 调用readFrames()时的想法是: 将上一帧和当前帧存储在缓冲区中 我想计算缓冲区中每对帧之间的运动值,但不阻塞函数readFrames(),因为计算该值时可以接收更多帧。我想我必须编写一个函数computeMotionValue(),每次我想执行它时,创建一个新线程并启动它。此函数应返回一些浮点运动值 每当任何线程返回的motionValue超过阈值时,我想+1一个公共

我有一个函数,它从视频流中接收前一帧和当前帧(让我们调用此函数,
readFrames()
)。该函数的任务是计算运动估计

调用
readFrames()
时的想法是:

  • 将上一帧和当前帧存储在缓冲区中
  • 我想计算缓冲区中每对帧之间的运动值,但不阻塞函数
    readFrames()
    ,因为计算该值时可以接收更多帧。我想我必须编写一个函数
    computeMotionValue()
    ,每次我想执行它时,创建一个新线程并启动它。此函数应返回一些
    浮点运动值
  • 每当任何线程返回的
    motionValue
    超过阈值时,我想+1一个公共int变量,我们称之为
    nValidMotion
  • 我的问题是,在访问
    motionValue
    nValidMotion
    时,我不知道如何“同步”线程


    您能用一些伪代码向我解释一下我该怎么做吗?

    以下是您可以使用的伪代码示例:

    // Following thread awaits notification from worker threads, detecting motion
    nValidMotion_woker_Thread()
    {
        while(true) { message_recieve(msg_q); ++nValidMotion; }
    }
    
    
    // Worker thread, computing motion on 2 frames; if motion detected, notify uysing message Q to nValidMotion_woker_Thread
    WorkerThread(frame1 ,frame2)
    {
        x =  computeMotionValue(frame1 ,frame2);
    
        if x > THRESHOLD
        msg_q.send();
    }
    
    // main thread
    main_thread()
    {
        // 1. create new message Q for inter-thread communication
        msg_q = new msg_q();
    
        // start listening thread
        Thread a = new nValidMotion_woker_Thread();
        a.start();
    
        while(true)
        {
            // collect 2 frames
            frame1 =  readFrames();
            frame2 =  readFrames();
    
            // start workre thread
            Thread b = new WorkerThread(frame1 ,frame2);
            b.start();      
        }
    }
    

    以下是您可以使用的伪代码示例:

    // Following thread awaits notification from worker threads, detecting motion
    nValidMotion_woker_Thread()
    {
        while(true) { message_recieve(msg_q); ++nValidMotion; }
    }
    
    
    // Worker thread, computing motion on 2 frames; if motion detected, notify uysing message Q to nValidMotion_woker_Thread
    WorkerThread(frame1 ,frame2)
    {
        x =  computeMotionValue(frame1 ,frame2);
    
        if x > THRESHOLD
        msg_q.send();
    }
    
    // main thread
    main_thread()
    {
        // 1. create new message Q for inter-thread communication
        msg_q = new msg_q();
    
        // start listening thread
        Thread a = new nValidMotion_woker_Thread();
        a.start();
    
        while(true)
        {
            // collect 2 frames
            frame1 =  readFrames();
            frame2 =  readFrames();
    
            // start workre thread
            Thread b = new WorkerThread(frame1 ,frame2);
            b.start();      
        }
    }
    
    每次我想要执行它时,创建一个新线程并启动它

    这通常是个坏主意。线程通常相当重,生成线程通常比只向现有线程池传递消息要慢

    无论如何,如果你落后了,你最终会得到比处理器内核更多的线程,然后由于上下文切换开销和内存压力,你会更加落后。最终创建一个新线程将失败

    我的问题是,在访问motionValue和nValidMotion时,我不知道如何“同步”线程

    对共享资源的访问的同步通常使用(互斥表示“互斥”,因为一次只能有一个线程持有锁)

    如果需要等待另一个线程执行某些操作,请使用wait/signal。您正在等待/发送某个共享资源状态的更改信号,因此也需要一个互斥锁

    对于这种处理,通常的建议是每个可用内核最多有一个线程,所有线程都服务于一个线程池。线程池有一个工作队列(由互斥锁保护,并由condvar发出空->非空转换信号)

    为了组合结果,您可以使用一个受互斥锁保护的全局计数器(但对于单个整数来说,这是相对较重的权重),或者您可以让添加到线程池的每个任务通过该机制返回bool,或者您可以让您的计数器返回bool

    每次我想要执行它时,创建一个新线程并启动它

    这通常是个坏主意。线程通常相当重,生成线程通常比只向现有线程池传递消息要慢

    无论如何,如果你落后了,你最终会得到比处理器内核更多的线程,然后由于上下文切换开销和内存压力,你会更加落后。最终创建一个新线程将失败

    我的问题是,在访问motionValue和nValidMotion时,我不知道如何“同步”线程

    对共享资源的访问的同步通常使用(互斥表示“互斥”,因为一次只能有一个线程持有锁)

    如果需要等待另一个线程执行某些操作,请使用wait/signal。您正在等待/发送某个共享资源状态的更改信号,因此也需要一个互斥锁

    对于这种处理,通常的建议是每个可用内核最多有一个线程,所有线程都服务于一个线程池。线程池有一个工作队列(由互斥锁保护,并由condvar发出空->非空转换信号)


    为了组合结果,您可以使用一个受互斥锁保护的全局计数器(但对于单个整数来说,这是一个相对较重的权重),或者您可以让添加到线程池的每个任务通过机制返回bool,或者您可以让您的计数器返回bool。

    您可以为此设置一个接收帧队列和一个线程。如您所述,为了计算运动值,您可以弹出2个最后输入的帧值和一个函数,这两个通过互斥和条件变量同步。您可以执行
    nValidMotion
    atomic,对它的任何访问都将自动同步。您正在寻找的解决方案是“生产者-消费者”问题的一种变体:在您的情况下,生产者线程读取帧并将其放入处理队列。此队列与使用者线程共享。两个线程都需要一种方法来同步它们对队列的访问,以防止一个线程从另一个线程下面拉出地毯。我的第一个快速搜索出现了这个例子,它看起来是学习线程的一个不错的起点:你可以有一个接收帧队列和一个线程。如您所述,为了计算运动值,您可以弹出2个最后输入的帧值和一个函数,这两个通过互斥和条件变量同步。您可以执行
    nValidMotion
    atomic,对它的任何访问都将自动同步。您正在寻找的解决方案是“生产者-消费者”问题的一种变体:在您的情况下,生产者线程读取帧并将其放入处理队列。此队列与使用者线程共享。两个线程都需要一种方法来同步它们对队列的访问,以防止一个线程从另一个线程下面拉出地毯。我的第一次快速搜索出现了这个例子,看起来这将是一个足够好的学习起点