anaVC94
anaVC94

Reputation: 13

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?

Upvotes: 0

Views: 110

Answers (2)

Useless
Useless

Reputation: 67812

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.

Upvotes: 2

nivpeled
nivpeled

Reputation: 1838

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

Upvotes: 0

Related Questions