简体   繁体   中英

Multithreading Implementation in C++

I am a beginner using multithreading in C++, so I'd appreciate it if you can give me some recommendations.

I have a function which receives the previous frame and current frame from a video stream (let's call this function, readFrames() ). The task of that function is to compute Motion Estimation.

The idea when calling readFrames() would be:

  1. Store the previous and current frame in a buffer.
  2. I want to compute the value of Motion between each pair of frames from the buffer but without blocking the function readFrames() , because more frames can be received while computing that value. I suppose I have to write a function computeMotionValue() and every time I want to execute it, create a new thread and launch it. This function should return some float motionValue .
  3. Every time the motionValue returned by any thread is over a threshold, I want to +1 a common int variable, let's call it nValidMotion .

My problem is that I don't know how to "synchronize" the threads when accessing motionValue and nValidMotion .

Can you please explain to me in some pseudocode how can I do that?

and every time I want to execute it, create a new thread and launch it

That's usually a bad idea. Threads are usually fairly heavy-weight, and spawning one is usually slower than just passing a message to an existing thread pool.

Anyway, if you fall behind, you'll end up with more threads than processor cores and then you'll fall even further behind due to context-switching overhead and memory pressure. Eventually creating a new thread will fail.

My problem is that I don't know how to "synchronize" the threads when accessing motionValue and nValidMotion.

Synchronization of access to a shared resource is usually handled with std::mutex (mutex means "mutual exclusion", because only one thread can hold the lock at once).

If you need to wait for another thread to do something, use std::condition_variable to wait/signal. You're waiting-for/signalling a change in state of some shared resource, so you need a mutex for that as well.

The usual recommendation for this kind of processing is to have at most one thread per available core, all serving a thread pool. A thread pool has a work queue (protected by a mutex, and with the empty->non-empty transition signalled by a condvar).

For combining the results, you could have a global counter protected by a mutex (but this is relatively heavy-weight for a single integer), or you could just have each task added to added to the thread pool return a bool via the promise/future mechanism, or you could just make your counter atomic .

Here is a sample pseudo code you may use:

// 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();      
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM