Sending data to thread in C++ - c++

I am having two classes one main class and another server class. I am calling run method in server class as a seperate thread from main class. I need to pass values from main class to server class periodically.
I tried using std::atomic but the value in the thread is not getting changed.
Am I doing something wrong below? Any help or advice is highly appreciated. THanks.
#include <iostream>
#include "server.h"
#include "atomic"
using namespace std;
std::atomic<int> clientSignal(-1);
void foo();
int main()
{
cout << "Hello World!" << endl;
server* board;
board = new server();
thread serverThread(&server::run,*board,std::ref(clientSignal));
serverThread.join();
foo(); // the value of clientSignal is changed from within main class //based on input from sensors.
return 0;
}
void foo(){
clientSignal = 8;
}
server.h
#ifndef SERVER_H
#define SERVER_H
class server
{
public:
server();
~server();
void run(std::atomic<int> &clientSignal);
private:
std::atomic<int> *clientFlag;
};
#endif // SERVER_H
server.cpp
#include "server.h"
server::server()
{
}
server::~server()
{
}
void server::run(std::atomic<int> &clientSignal) {
clientFlag = &clientSignal;
cout << *clientFlag;
...
}

Related

QThreadPoolServer is not responding

I wrote a simple threadpool server with qt. When i try to connect to server on win 32/64 all works good. But when I use linux centos 7 server is not responding. I use 127.0.0.1:8080 for server address. Also server uses database mysql. When I try to connect via telnet it connects but nothing happens. I checked for open ports with netstat. Maybe I missed something because of this the server is not working?
Here is my code for server. In fact, there is also an http request handler, but it does not reach it, I tried to output a string in the constructor - it is not called.
QthreadPoolServer.cpp
#include "QThreadPoolServer.h"
#include "QSocketRunnable.h"
#include "ConfigReader.h"
#include <memory>
QThreadPoolServer::QThreadPoolServer()
{
ConfigReader reader(config_file_path);
QHostAddress server_IP(reader.getServerAddress());
int port = reader.getServerPort();
listen(QHostAddress::localhost, 8080);
std:: cout << serverError() << errorString().toStdString();
m_threadPool = std::make_shared<QThreadPool>(this);
}
void QThreadPoolServer::incomingConnection(int handle)
{
std::shared_ptr<QSocketRunnable> runnable = std::make_shared<QSocketRunnable>(handle);
runnable->setAutoDelete(false);
m_threadPool->start(runnable.get());
}
QThreadPoolServer::~QThreadPoolServer()
{
m_threadPool->~QThreadPool();
}
QThreadPoolServer.h
#ifndef QTHREADPOOLSERVER_H
#define QTHREADPOOLSERVER_H
#include <QTcpServer>
#include <QThreadPool>
#include <memory>
class QThreadPoolServer : public QTcpServer
{
public:
explicit QThreadPoolServer();
void incomingConnection(int handle);
~QThreadPoolServer();
private:
std::shared_ptr<QThreadPool> m_threadPool;
};
#endif // QTHREADPOOLSERVER_H
QSocketRunnable.cpp
#include "QSocketRunnable.h"
#include <QString>
#include <memory>
#include <iostream>
QSocketRunnable::QSocketRunnable(int handle) : m_descriptor(handle) { }
void QSocketRunnable::run()
{
QTcpSocket* socket = new QTcpSocket();
socket->setSocketDescriptor(m_descriptor);
socket->waitForReadyRead();
QString request_data = QString(socket->readAll());
HttpRequestHandler handler(request_data);
handler.makeResponse();
QString http_response_result = handler.getHttpResponse();
std::cout << http_response_result.toStdString() << "\n";
socket->write(http_response_result.toUtf8());
socket->waitForBytesWritten(90000);
socket->disconnectFromHost();
socket->close();
socket->deleteLater();
}
QSocketRunnable.h
#ifndef QSOCKETRUNNABLE_H
#define QSOCKETRUNNABLE_H
#include <QRunnable>
#include <QTcpSocket>
#include <QtDebug>
#include <QString>
//#include "IDHelper.h"
//#include "JsonFormatter.h"
//#include "HttpRequestHandler.h"
class QSocketRunnable : public QRunnable
{
public:
QSocketRunnable(int handle);
void run() override;
private:
int m_descriptor;
};
#endif // QSOCKETRUNNABLE_H
main.cpp
#include <QCoreApplication>
#include "QThreadPoolServer.h"
#include "signal.h"
#include <sstream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QThreadPoolServer server;
return a.exec();
}
Also std:: cout << serverError() << errorString().toStdString(); returns "-1" that means QAbstractSocket::UnknownSocketError -1 An unidentified error occurred.
As #chehrlic correctly noted: I had an incorrectly overloaded function, so here is the ritht version of QThreadPoolServer.h
QThreadPoolServer.h
#ifndef QTHREADPOOLSERVER_H
#define QTHREADPOOLSERVER_H
#include <QTcpServer>
#include <QThreadPool>
#include <memory>
class QThreadPoolServer : public QTcpServer
{
public:
explicit QThreadPoolServer();
protected:
void incomingConnection(qintptr handle) override;
~QThreadPoolServer();
private:
std::shared_ptr<QThreadPool> m_threadPool;
};
#endif // QTHREADPOOLSERVER_H
My my implementation did not work correctly with a smart pointer to a runnable object:
QThreadPoolServer.cpp
void QThreadPoolServer::incomingConnection(qintptr handle)
{
QSocketRunnable* runnable = new QSocketRunnable(handle)
runnable->setAutoDelete(true);
m_threadPool->start(runnable);
}

Emit safely a signal from a thread and connect it to a widget

I'm using Gtkmm and multithreading.
I have a class "NetworkWorker" doig stuffs with the network in a secondary thread.
In this class i want to make many signals which will be handled by my class "MainWindow".
The methods which handle these signals, will edit append text in a TextView.
I have the following code:
NetworkWorker.h
#ifndef NETWORKWORKER_H_
# define NETWORKWORKER_H_
# include <sigc++/sigc++.h>
# include <glibmm/threads.h>
# include <string>
class NetworkWorker
{
public:
NetworkWorker();
~NetworkWorker();
void start();
void stop();
sigc::signal<void, std::string&>& signal_data_received();
private:
void run();
sigc::signal<void, std::string&> m_signal_data_received;
Glib::Threads::Thread* m_thread;
Glib::Threads::Mutex m_mutex;
bool m_stop;
};
#endif
NetworkWorker.c
#include <cstdlib>
#include <glibmm/timer.h>
#include <glibmm/threads.h>
#include <iostream>
#include <sigc++/sigc++.h>
#include "NetworkWorker.h"
NetworkWorker::NetworkWorker() :
m_thread(NULL), m_stop(false)
{
}
NetworkWorker::~NetworkWorker()
{
stop();
}
void NetworkWorker::start()
{
if (!m_thread)
m_thread = Glib::Threads::Thread::create(sigc::mem_fun(*this, &NetworkWorker::run));
}
void NetworkWorker::stop()
{
{
Glib::Threads::Mutex::Lock lock(m_mutex);
m_stop = true;
}
if (m_thread)
m_thread->join();
}
sigc::signal<void, std::string&>& NetworkWorker::signal_data_received()
{
return m_signal_data_received;
}
void NetworkWorker::run()
{
while (true)
{
{
Glib::Threads::Mutex::Lock lock(m_mutex);
if (m_stop)
break;
}
Glib::usleep(5000);
std::cout << "Thread" << std::endl;
std::string* str = new std::string("MyData");
m_signal_data_received.emit(*str);
}
}
MainWindow.h
#ifndef MAIN_WINDOW_H_
# define MAIN_WINDOW_H_
# include <gtkmm/textview.h>
# include <gtkmm/window.h>
# include <string>
class MainWindow : public Gtk::Window
{
public:
MainWindow();
~MainWindow();
void appendText(const std::string& str);
private:
Gtk::TextView m_text_view;
};
#endif
MainWindow.c
#include <gtkmm/notebook.h>
#include <gtkmm/widget.h>
#include <iostream>
#include <string>
#include "MainWindow.h"
MainWindow::MainWindow()
{
set_title("My App");
set_default_size(800, 600);
add(m_text_view);
}
MainWindow::~MainWindow()
{
}
void MainWindow::appendText(const std::string& str)
{
std::string final_text = str + "\n";
Glib::RefPtr<Gtk::TextBuffer> buffer = m_text_view.get_buffer();
Gtk::TextBuffer::iterator it = buffer->end();
buffer->insert(it, final_text);
Glib::RefPtr<Gtk::Adjustment> adj = m_text_view.get_vadjustment();
adj->set_value(adj->get_upper() - adj->get_page_size());
}
and my main.cpp
#include <cstdlib>
#include <gtkmm/main.h>
#include <iostream>
#include <string>
#include "MainWindow.h"
#include "NetworkWorker.h"
void recv(const std::string& str)
{
std::cout << str << std::endl;
}
int main(int argc, char **argv)
{
Gtk::Main app(Gtk::Main(argc, argv));
MainWindow main_window;
NetworkWorker network_worker;
main_window.show_all();
network_worker.signal_data_received().connect(sigc::ptr_fun(&recv));
network_worker.signal_data_received().connect(sigc::mem_fun(main_window, &MainWindow::appendText));
network_worker.start();
Gtk::Main::run(main_window);
return (EXIT_SUCCESS);
}
These snippetes have been a re-adapted for this question, so maybe some change is incoherent.
When I execute this code, I have the following output:
$> ./client
Thread
MyData
Thread
MyData
[...]
Thread
MyData
Thread
MyData
(client:5596): Gtk-CRITICAL **: gtk_text_layout_real_invalidate: assertion 'layout->wrap_loop_count == 0' failed
Thread
MyData
Thread
MyData
[...]
Thread
MyData
Thread
MyData
[1] 5596 segmentation fault (core dumped) ./client
Can some one help me to resolve this issue ? :)
The issue is you are calling non threadsafe function call (signal callbacks are not threadsafe).
So you need to use something like Glib::signal_idle().connect( sigc::mem_fun(*this, &IdleExample::on_idle) );(or whatever is equivalent to C API call g_idle_add(GCallback func)) from your thread. This function is threadsafe (at least the one from the C API).
See this tutorial for a simplified example.
Never call or signal from different threads when using UI libraries. Usually the APIs are designed to be called from a single thread. This is the single most often made mistake when using UI toolkits.

using class instance on two classes..c++

I basically do not know how to ask this question, I am fairly new to c++...anyway my problem is, I am trying to create this vendingmachine class and this user class, the user needs to have access to the insertCoins method and makePurchase methods from vendingMachine.cpp I tried creating an instance of the class vending machine inside the method calls in user.cpp as it is here, but when I try to list the items in vending machine obviously the list is untouched because theinstance I create inside the method calls in user.cpp are just temporary...how would I get a global instance so that I use it within user.cpp while using it within vending machine inside main.cpp...
#include "user.h"
#include "VendingMachine.h"
user::user(){
}
user::~user(){
}
void user::makePurchase(int choice){
VendingMachine vm;
vm.purchaseProduct(choice);
}
void user::insertCoins(double coin){
VendingMachine vm;
vm.insertCoins(coin);
}
~~~~~~~~~~~~~
#include "VendingMachine.h"
#include "machineOperator.h"
#include "user.h"
using namespace std;
int main(){
VendingMachine vm = VendingMachine();
user u = user();
vm.listProducts();
cout << endl;
u.insertCoins(1.0);
u.insertCoins(1.0);
u.makePurchase(2);
vm.listProducts();
cout << endl;
return 0;
}
~~~~~~~~~~~~~~~~~~~
/*
* user.h
*
* Created on: Jan 12, 2014
* Author: Andrey
*/
#ifndef USER_H_
#define USER_H_
class user {
public:
user();
~user();
void makePurchase(int);
void insertCoins(double);
};
#endif /* USER_H_ */
It is natural to assume that a user can purchase from and insert coin to many different vending machines.
void user::makePurchase (VendingMachine &vm, int choice)
{
vm.purchaseProduct(choice);
}
void user::insertCoins (VendingMachine &vm, double coin)
{
vm.insertCoins(coin);
}
Use a pointer to the VendingMachine in your user and pass it in to the constructor.
user.h
class VendingMachine;
class User {
private:
VendingMachine* vm;
}
user.cc
#include "user.h"
#include "vendingmachine.h"
User::User(VendingMachine* vm): vm(vm) {}
void User::makePurchase(int choice){
vm->purchaseProduct(choice);
}
void User::insertCoins(double coin){
vm->insertCoins(coin);
}
main.cc
#include "VendingMachine.h"
#include "machineOperator.h"
#include "user.h"
using namespace std;
int main(){
VendingMachine vm = VendingMachine();
User u = User(&vm);
vm.listProducts();
cout << endl;
u.insertCoins(1.0);
u.insertCoins(1.0);
u.makePurchase(2);
vm.listProducts();
cout << endl;
return 0;
}

How to correctly extend a class in C++ and writing its header file?

I've got a third party library named person.lib and its header person.h. This is my actual project structure and it compiles and runs perfectly.
Actual Structure:
main.cpp
#include <iostream>
#include <time.h>
#include <ctype.h>
#include <string>
#include "person.h"
using namespace person;
using namespace std;
class Client : public Person
{
public:
Client();
void onMessage(const char * const);
private:
void gen_random(char*, const int);
};
Client::Client() {
char str[11];
gen_random(str, 10);
this->setName(str);
}
void Client::onMessage(const char * const message) throw(Exception &)
{
cout << message << endl;
}
void Client::gen_random(char *s, const int len) {
//THIS FUNCTION GENERATES A RANDOM NAME WITH SPECIFIED LENGTH FOR THE CLIENT
}
int main()
{
try
{
Person *p = new Client;
p->sayHello();
}
catch(Exception &e)
{
cout << e.what() << endl;
return 1;
}
return 0;
}
I want to refactor my code by dividing the declaration of my Client class from its definition and create client.h and client.cpp. PAY ATTENTION: sayHello() and onMessage(const * char const) are functions of the person library.
Refactored Structure:
main.cpp
#include <iostream>
#include "client.h"
using namespace person;
using namespace std;
int main()
{
try
{
Person *p = new Client;
p->sayHello();
}
catch(Exception &e)
{
cout << e.what() << endl;
return 1;
}
return 0;
}
client.cpp
#include "client.h"
using namespace person;
using namespace std;
Client::Client() {
char str[11];
gen_random(str, 10);
this->setName(str);
}
void Client::onMessage(const char * const message) throw(Exception &)
{
cout << message << endl;
}
void Client::gen_random(char *s, const int len) {
//THIS FUNCTION GENERATES A RANDOM NAME WITH SPECIFIED LENGTH FOR THE CLIENT
}
client.h
#ifndef CLIENT_H
#define CLIENT_H
#include <time.h>
#include <ctype.h>
#include <string>
#include "person.h"
class Client : public Person
{
public:
Client();
void onMessage(const char * const);
private:
void gen_random(char*, const int);
};
#endif
As you can see, I've simply created a client.h in which there's the inclusion of the base class person.h, then I've created client.cpp in which there's the inclusion of client.h and the definitions of its functions. Now, the compilation gives me these errors:
error C2504: 'Person': base class undefined client.h 7 1 Test
error C2440: 'inizialization': unable to convert from 'Client *' to 'person::impl::Person *' main.cpp 15 1 Test
error C2504: 'Person': base class undefined client.h 7 1 Test
error C2039: 'setName': is not a member of 'Client' client.cpp 8 1 Test
error C3861: 'sendMessage': identifier not found client.cpp 34 1 Test
It's a merely cut&copy refactoring but it doesn't work and I really don't understand WHY! What's the solution and why it gives me these errors? Is there something about C++ structure that I'm missing?
Here's a dog-n-bird implementation (ruff ruff, cheep cheep)
cLawyer is defined and implemented in main.cpp, while cPerson and cClient are defined in their own header files, implemented in their own cpp file.
A better approach would store the name of the class. Then, one wouldn't need to overload the speak method - one could simply set the className in each derived copy. But that would have provided in my estimates, a less useful example for you.
main.cpp
#include <cstdio>
#include "cClient.h"
class cLawyer : public cPerson
{
public:
cLawyer() : cPerson() {}
~cLawyer() {}
void talk(char *sayWhat){printf("cLawyer says: '%s'\n", sayWhat);}
};
int main()
{
cPerson newPerson;
cClient newClient;
cLawyer newLawyer;
newPerson.talk("Hello world!");
newClient.talk("Hello world!");
newLawyer.talk("Hello $$$");
return 0;
}
cPerson.h
#ifndef cPerson_h_
#define cPerson_h_
class cPerson
{
public:
cPerson();
virtual ~cPerson();
virtual void talk(char *sayWhat);
protected:
private:
};
#endif // cPerson_h_
cPerson.cpp
#include "cPerson.h"
#include <cstdio>
cPerson::cPerson()
{
//ctor
}
cPerson::~cPerson()
{
//dtor
}
void cPerson::talk(char *sayWhat)
{
printf("cPerson says: '%s'\n",sayWhat);
}
cClient.h
#ifndef cClient_h_
#define cClient_h_
#include "cPerson.h"
class cClient : public cPerson
{
public:
cClient();
virtual ~cClient();
void talk(char *sayWhat);
protected:
private:
};
#endif // cClient_h_
cClient.cpp
#include "cClient.h"
#include <cstdio>
cClient::cClient()
{
//ctor
}
cClient::~cClient()
{
//dtor
}
Output
cPerson says: 'Hello world!'
cClient says: 'Hello world!'
cLawyer says: 'Hello $$$'
Suggestions noted above:
//In the cPerson class, a var
char *m_className;
//In the cPerson::cPerson constructer, set the var
m_className = "cPerson";
//Re-jig the cPerson::speak method
void cPerson::speak(char *sayWhat)
{
printf("%s says: '%s'\n", m_className, sayWhat);
}
// EDIT: *** remove the speak methods from the cClient and cLawyer classes ***
//Initialize the clas name apporpriately in derived classes
//cClient::cClient
m_className = "cClient";
//Initialize the clas name apporpriately in derived classes
//cLaywer::cLaywer
m_className = "cLawyer";
You are declaring the class Client twice - once in the .h file and once in .cpp. You only need to declare it in the .h file.
You also need to put the using namespace person; to the .h file.
If class Person is in namcespace person, use the person::Person to access it.
The client.cpp must contain definitions only!
I think for the linker the class Client defined in client.h and class Client defined in client.cpp are different classes, thus it cannot find the implementation of Client::Client(). I purpose to remove the declaration of class Client from the client.cpp and leave there only definitions of functions:
// client.cpp
#include <time.h>
#include <ctype.h>
#include <string>
#include "client.h"
using namespace std;
Client::Client()
{
//DO STUFF
}
void Client::onMessage(const char * const message)
{
//DO STUFF
}
void Client::gen_random(char *s, const int len) {
//DO STUFF
}

qt multithreading: calculating an intergral

I need to calculate an integral using the trapezoidal rule and multithreading.
I am using a pool thread that I wrote using a java pool thread example.
#ifndef POOL_H
#define POOL_H
#include <QObject>
#include <QThread>
#include <QWaitCondition>
#include <QMutex>
#include <QQueue>
#include "poolworker.h"
#include "segment.h"
class Segment;
class PoolWorker;
class Pool: public QObject
{
Q_OBJECT
public:
explicit Pool(QObject *parent = 0);
Pool(int nThreads);
void execute(Segment *s);
static QWaitCondition con;
static QMutex poolMutex;
static QQueue<Segment*> segmentQueue;
private:
int nThreads;
QVector<PoolWorker*> workers;
};
#endif // POOL_H
#include "pool.h"
QWaitCondition Pool::con;
QQueue<Segment*> Pool::segmentQueue;
QMutex Pool::poolMutex;
Pool::Pool(QObject *parent) :
QObject(parent)
{
}
Pool::Pool(int nThreads)
{
this->nThreads = nThreads;
for (int i = 0; i < nThreads; i++)
{
workers.push_back(new PoolWorker());
workers[i]->start();
}
}
void Pool::execute(Segment *s)
{
poolMutex.lock();
segmentQueue.enqueue(s);
con.wakeOne();
poolMutex.unlock();
}
#ifndef POOLWORKER_H
#define POOLWORKER_H
#include <QThread>
#include <QMutex>
#include "segment.h"
#include "pool.h"
class PoolWorker : public QThread
{
Q_OBJECT
public:
explicit PoolWorker(QObject *parent = 0);
void run();
static QMutex mutex;
signals:
public slots:
private:
};
#endif // POOLWORKER_H
#include "poolworker.h"
QMutex PoolWorker::mutex;
PoolWorker::PoolWorker(QObject *parent) :
QThread(parent)
{
}
void PoolWorker::run()
{
Segment *temp;
forever
{
mutex.lock();
while(Pool::segmentQueue.isEmpty())
{
Pool::con.wait(&mutex);
}
temp = Pool::segmentQueue.dequeue();
mutex.unlock();
temp->doWork();
}
}
Each interval is put into a container "Segment" which also calculates the integral.
Sab = 0.5*(b-a)*(f(a)+f(b))
m = (a+b)/2.0
Sam = 0.5*(m-a)*(f(a)+f(m))
Smb = 0.5*(b-m)*(f(b)+f(m))
If the difference between Sab and Sam+Smb is lower than Eps, then I add Sab to the integral sum using Manager::addSum. If it's not lower, I do the same algorithm for am and mb. etc.
#ifndef SEGMENT_H
#define SEGMENT_H
#include <QObject>
#include <cmath>
#include "manager.h"
#include <QDebug>
class Segment : public QObject
{
Q_OBJECT
private:
double a,b,Sab,Sam,Smb,m,Eps;
double f(double x);
public:
explicit Segment(QObject *parent = 0);
Segment(double a, double b);
void doWork();
signals:
public slots:
};
#endif // SEGMENT_H
#include "segment.h"
Segment::Segment(QObject *parent) :
QObject(parent)
{
}
Segment::Segment(double a, double b)
{
this->a = a;
this->b = b;
Eps = 0.001;
}
void Segment::doWork()
{
Sab = 0.5*(b-a)*(f(a)+f(b));
m = (a+b)/2.0;
Sam = 0.5*(m-a)*(f(a)+f(m));
Smb = 0.5*(b-m)*(f(b)+f(m));
if (fabs(Sab - (Sam + Smb)) <= Eps)
{
Manager::addSum(Sab);
qDebug() << "Reached Eps on interval a= " << a << ",b = " << b
<< ", return S+= " << Sab;
Manager::inc();
}
else
{
Manager::threadPool->execute(new Segment(a,m));
Manager::threadPool->execute(new Segment(m,b));
}
}
double Segment::f(double x)
{
return pow(x,3.0) - 4.0*pow(x,2.0) + 6.0*x - 24.0;
}
The Manager class ties everything in: it creates the pool, contains the sum and starts the calculation by calling execute on pool with the first interval. It also has a counter for debugging purposes.
#ifndef MANAGER_H
#define MANAGER_H
#include <QObject>
#include <QThread>
#include <QQueue>
#include <QVector>
#include "segment.h"
#include "pool.h"
class Pool;
class Manager : public QObject
{
Q_OBJECT
private:
static double sum;
static int i;
static QMutex mutex;
public:
explicit Manager(QObject *parent = 0);
static Pool *threadPool;
static void addSum(double add);
static void inc();
double viewSum();
int viewCount();
void doSetup(QThread &thread);
signals:
public slots:
void doWork();
};
#endif // MANAGER_H
#include "manager.h"
double Manager::sum = 0;
int Manager::i = 0;
Pool* Manager::threadPool = new Pool(10);
QMutex Manager::mutex;
Manager::Manager(QObject *parent) :
QObject(parent)
{
}
void Manager::addSum(double add)
{
mutex.lock();
sum += add;
mutex.unlock();
}
void Manager::inc()
{
i++;
}
double Manager::viewSum()
{
return sum;
}
int Manager::viewCount()
{
return i;
}
void Manager::doSetup(QThread &thread)
{
connect(&thread,SIGNAL(started()),this,SLOT(doWork()));
}
void Manager::doWork()
{
threadPool->execute(new Segment(4.5,12.0));
}
In main I create the manager, a thread for the manager and display the results.
#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include <QTimer>
#include "manager.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Manager man;
QThread manThread;
man.doSetup(manThread);
man.moveToThread(&manThread);
manThread.start();
manThread.wait(2500);
qDebug() << "integrate(x^3 - 4*x^2 + 6*x - 24) from 4.5 to 12.0 = "
<< man.viewSum();
qDebug() << "i =" << man.viewCount();
manThread.quit();
QTimer::singleShot(1000, &a, SLOT(quit()));
return a.exec();
}
It calculates the integral correctly about half of the time. The other half I get a larger number than expected(which varies). When I get a larger number, I notice that some of the intervals are calculated twice. If I'm not mistaken I have made the code thread-safe so I don't understand how this happens. I'm pretty new to multithread programming so I might be doing something wrong with mutexes? Or maybe my transition from the java pool is wrong?
Another thing is in main.cpp I'm not sure how to properly display the results since I don't know when the integral is done calculating. I am using a wait(2500) function on the thread that contains the manager but it's not a really good method since the calculation time may vary on different PC's and for different functions.
Thanks in advance for any help you are able to provide.
You got your locking wrong. In the Java example you pointed to, the same lock (the queue itself) is used in enqueueing (in execute) and dequeueing (in the worker threads). That way, the queue operations are really threadsafe. In your code unfortunately, you use two different locks. Pool::poolMutex for enque (in execute) and PoolWorker::mutex for deque (in the PoolWorker thread). That way, you guard the queue only for deque between threads, but deque and enque can happen concurrently. Your Pool::poolMutex is useless because execute is being called only by one thread, so it is being locked and unlocked only by one thread. You need to use only one and the same mutex for enque and deque. Pass the Pool::poolMutex into PoolWorker via constructor and lock on it instead of PoolWorker::mutex.
So when you enque and some thread has just finished working, it will deque immediately (because queue is not empty), not waiting for your wakeOne. Then on wakeOne, you will fire off another thread. I don't have a clear explanation of how the two threads can grab the same job (and not crash), but your code will definitely work better if you use only one lock as in the Java original.