Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 859345
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T08:40:09+00:00 2026-05-15T08:40:09+00:00

I have to write a program that performs highly computationally intensive calculations. The program

  • 0

I have to write a program that performs highly computationally intensive calculations. The program might run for several days.
The calculation can be separated easily in different threads without the need of shared data.
I want a GUI or a web service that informs me of the current status.

My current design uses BOOST::signals2 and BOOST::thread.
It compiles and so far works as expected.
If a thread finished one iteration and new data is available it calls a signal which is connected to a slot in the GUI class.

My question(s):

  • Is this combination of signals and threads a wise idea? I another forum somebody advised someone else not to “go down this road”.
  • Are there potential deadly pitfalls nearby that I failed to see?
  • Is my expectation realistic that it will be “easy” to use my GUI class to provide a web interface or a QT, a VTK or a whatever window?
  • Is there a more clever alternative (like other boost libs) that I overlooked?

following code compiles with

g++ -Wall -o main -lboost_thread-mt <filename>.cpp

code follows:

#include <boost/signals2.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

#include <iostream>
#include <iterator>
#include <string>

using std::cout;
using std::cerr;
using std::string;

/**
 * Called when a CalcThread finished a new bunch of data.
 */
boost::signals2::signal<void(string)> signal_new_data;

/**
 * The whole data will be stored here.
 */
class DataCollector
{
    typedef boost::mutex::scoped_lock scoped_lock;
    boost::mutex mutex;

public:
    /**
     * Called by CalcThreads call the to store their data.
     */
    void push(const string &s, const string &caller_name)
    {
        scoped_lock lock(mutex);
        _data.push_back(s);
        signal_new_data(caller_name);
    }

    /**
     * Output everything collected so far to std::out.
     */
    void out()
    {
        typedef std::vector<string>::const_iterator iter;
        for (iter i = _data.begin(); i != _data.end(); ++i)
            cout << " " << *i << "\n";
    }

private:
    std::vector<string> _data;
};

/**
 * Several of those can calculate stuff.
 * No data sharing needed.
 */
struct CalcThread
{
    CalcThread(string name, DataCollector &datcol) :
        _name(name), _datcol(datcol)
    {

    }

    /**
     * Expensive algorithms will be implemented here.
     * @param num_results how many data sets are to be calculated by this thread.
     */
    void operator()(int num_results)
    {
        for (int i = 1; i <= num_results; ++i)
        {
            std::stringstream s;
            s << "[";
            if (i == num_results)
                s << "LAST ";
            s << "DATA " << i << " from thread " << _name << "]";
            _datcol.push(s.str(), _name);
        }
    }

private:
    string _name;
    DataCollector &_datcol;
};

/**
 * Maybe some VTK or QT or both will be used someday.
 */
class GuiClass
{
public:
    GuiClass(DataCollector &datcol) :
        _datcol(datcol)
    {

    }

    /**
     * If the GUI wants to present or at least count the data collected so far.
     * @param caller_name is the name of the thread whose data is new.
     */
    void slot_data_changed(string caller_name) const
    {
        cout << "GuiClass knows: new data from " << caller_name << std::endl;
    }

private:
    DataCollector & _datcol;

};

int main()
{
    DataCollector datcol;

    GuiClass mc(datcol);
    signal_new_data.connect(boost::bind(&GuiClass::slot_data_changed, &mc, _1));

    CalcThread r1("A", datcol), r2("B", datcol), r3("C", datcol), r4("D",
            datcol), r5("E", datcol);

    boost::thread t1(r1, 3);
    boost::thread t2(r2, 1);
    boost::thread t3(r3, 2);
    boost::thread t4(r4, 2);
    boost::thread t5(r5, 3);

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    t5.join();

    datcol.out();

    cout << "\nDone" << std::endl;
    return 0;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T08:40:10+00:00Added an answer on May 15, 2026 at 8:40 am

    Is this combination of signals and
    threads a wise idea? I another forum
    somebody advised someone else not to
    “go down this road”.

    It seems to be sound. Can you provide a link to the other thread? Were they explaining their reasoning?

    Are there potential deadly pitfalls nearby that I failed to see?

    If they are I fail to see them also. What you need to take care of is that the notifications are thread-safe (the triggering of the signal doesn’t switch thread contexts, to your GuiClass::slot_data_changed should be called from all the other threads.

    Is my expectation realistic that it will be “easy” to use my GUI class to provide a web interface or a QT, a VTK or a whatever window?

    It will not be easy. To fix this, you’d have to make your notification switch threading contexts. Here’s what I would do:

    Have your GuiClass be an abstract base class, implementing it’s own message queue. When GuiClass::slot_data_changed is called by your threads, you lock a mutex and post a copy of the received notification on an internal (private:) message queue. In the thread of the GuiClass you create a function that locks the mutex and looks for notifications in the queue. This function should run in the client code’s thread (in the thread of the concrete classes you specialize from the abstract GuiClass).

    Advantages:

    • your base class encapsulates and isolates the thread context switching, transparently to it’s specializations.

    Disadvantages:

    • your client code has to either run the polling method or allow it to run (as a thread-processing function).

    • it’s a bit complicated 🙂

    Is my expectation realistic that it
    will be “easy” to use my GUI class to
    provide a web interface or a QT, a VTK
    or a whatever window?

    Doesn’t see so, but it’s not so easy. Besides the thread context-switching there may be other issues I’m missing at the moment.

    Is there a more clever alternative
    (like other boost libs) that I
    overlooked?

    Not other boost libs, but the way you wrote your threads is not good: the joins are made sequentially in your code. To have only one join for all threads, use a boost::thread_group.

    Instead of:

    boost::thread t1(r1, 3);
    boost::thread t2(r2, 1);
    boost::thread t3(r3, 2);
    boost::thread t4(r4, 2);
    boost::thread t5(r5, 3);
    
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    t5.join();
    

    you will have:

    boost::thread_group processors;
    processors.create_thread(r1, 3);
    // the other threads here
    
    processors.join_all();
    

    Edit: A thread context is everything that is specific to a particular running thread (thread-specific storage, the stack of that thread, any exceptions thrown in that thread’s context and so on).

    When you have various thread contexts in the same application (multiple threads) you need to synchronize access to resources created within a thread context and accessed from different threads (using locking primitives).

    For example, let’s say you have a, an instance of class A [running in thread tA] doing some stuff and b, an instance of class B [running in the context of thread tB] and b wants to tell a something.

    The “wants to tell a something” part means that b wants to call a.something() and a.something() will be called in the context of tB (on the stack of thread B).

    To change this (to have a.something() run in the context of tA), you have to switch the thread context. This means that instead of b telling a “run A::something()“, b tells a “run A::something()` in your own thread context”.

    Classical implementation steps:

    • b sends a message to a from within tB

    • a polls for messages from within tA

    • When a finds the message from b, it runs a.something() itself, within tA.

    This is the switching of threading contexts (the execution of A::something will be executed in tA instead of tB, as it would have been if called directly from b).

    From the link you provided, it seems this is already implemented by boost::asio::io_service, so if you use that, you don’t have to implement it yourself.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 438k
  • Answers 438k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer if you have to use many global variables inside of… May 15, 2026 at 4:40 pm
  • Editorial Team
    Editorial Team added an answer You need to put a semicolon instead of a colon… May 15, 2026 at 4:40 pm
  • Editorial Team
    Editorial Team added an answer You should probably use two passes for your search. In… May 15, 2026 at 4:40 pm

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.