Using a ThreadPool inside a loop - c++

I have a service that runs without stopping.
While the software runs I call some GET and POST functions that I don't need to wait a response. Speed is important
Today I am doing like bellow, an simple example:
boost::asio::thread_pool ThreadPool(16);
int main(){
while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0){
string Event = "test";
boost::asio::post(ThreadPool, [=]() {
sendPOSTEvent(Event);
}
}
ThreadPool.stop();
ThreadPool.join();
}
Is that correct? Or can I have problems? Do I need to clean something inside the loop?

Related

C++ async function call without waiting and return - how to?

How to generate async function calls like in JS (you fire it and it goes to work independently)?
while(true)
{
if(s == "123")
//fire an async function to do some work and continue the cycle immediately
}
I do not need to wait, just start an average function with params to run when the system has time, but the cycle must not to be paused and waiting. It will run on Linux.
EDIT:
If I use it like this:
while(true)
{
if(s == "123")
std::future<std::string> resultFromDB = std::async(std::launch::async, fetchDataFromDB, "Data");
}
, will it be a problem, that resultFromDB gets another async assigned in each cycle run?

boost::asio::io_service.post() background thread memory usage

I want to run boost::asio::io_service.run() in a background thread. So when I need it post() func into.
This is main func:
int main(int /*argc*/, char** /*argv*/)
{
std::string message = "hello";
logg = new logger_client(filename,ip,13666);
logg->start();
while (true)
logg->add_string(message);
return 0;
}
And some relevant funcs from logger_client:
std::auto_ptr<boost::asio::io_service::work> work;
logger_client::logger_client(std::string& filename,std::string& ip, uint16_t port) : work(new boost::asio::io_service::work(io_service))
{
}
void logger_client::start()
{
ios_thread = new boost::thread(boost::bind(&io_service.run,&io_service));
}
void print_nothing()
{
printf("%s\n","lie");
}
void logger_client::add_string(std::string& message)
{
io_service.post(boost::bind(print_nothing));
//io_service.post(strand->wrap(boost::bind(&logger_client::add_string_imp,this,message)));
//io_service.run();
}
When i run this, my program eats 2Gb less than a minute. If i remove endless work and change to this:
void logger_client::add_string(std::string& message)
{
io_service.post(boost::bind(print_nothing));
//io_service.post(strand->wrap(boost::bind(&logger_client::add_string_imp,this,message)));
io_service.run();
}
Program works just fine. But I don't want to invoke async operations on this (main) thread. What am i doing wrong?
UPDATE
I added sleep(1sec) in while(true) loop and memory is no longer growing. But this is not a solution. Because if I call run() after post() (i.e. use main thread for processing handles) and even add five more threads with while(true) loops memory is not growing. So why main thread is so much better than newly created? I also tried thread pool for io_service::run - did not help.
io_service.run will exit unless there are pending operations.
Therefore, your ios_thread will exit immediately.
The solution is to use io_service::work.
In addition, endless loop spam like this
while (true)
logg->add_string(message);
is not a good idea, maybe add some sleep(), to slow it down a bit and keep it under control.

How to wait on a Mutex with OpenMP

I've a for loop that will launch processes in parallel every launched process will return a response back indicating that it is ready. I want to wait for the response and I'll abort if a certain timeout is reached.
Development environment is VS2008
Here is the pseudo code:
void executeCommands(std::vector<Command*> commands)
{
#pragma omp parallel for
for (int i = 0; i < commands.size(); i++)
{
Command* cmd = commands[i];
DWORD pid = ProcessLauncher::launchProcess(cmd->getWorkingDirectory(), cmd->getCommandToExcecute(), cmd->params);
//Should I wait for process to become ready?
if (cmd->getWaitStatusTimeout() > 0)
{
ProcessStatusManager::getInstance().addListener(*this);
//TODO: emit process launching signal
//BEGINNING OF QUESTION
//I don't how to do this part.
//I might use QT's QWaitCondition but if there is another solution in omp
//I'd like to use it
bool timedOut;
SOMEHANDLE handle = Openmp::waitWithTimeout(cmd->getWaitStatusTimeout(), &timedOut);
mWaitConditions[pid]) = handle;
//END OF QUESTION
if (timedOut)
{
ProcessStatusManager::getInstance().removeListener(*this);
//TODO: kill process
//TODO: emit fail signal
}
else
{
//TODO: emit process ready signal
}
}
else
{
//TODO: emit process ready signal
}
}
}
void onProcessReady(DWORD sourceProcessPid)
{
ProcessStatusManager::getInstance().removeListener(*this);
SOMEHANDLE handle = mWaitConditions[sourceProcessPid];
if (mWaitConditions[sourceProcessPid] != 0)
{
Openmp::wakeAll(handle);
}
}
As the comment above pointed out, Michael Suess did present a paper on adding this functionality to OpenMP. He is the last of several people that have proposed adding some type of wait function to OpenMP. The OpenMP language committee has taken the issue up several times. Each time it has been rejected because there are other ways to do this function already. I don't know Qt, but as long as the functions it provides are thread safe, then you should be able to use them.

gSoap: how to gracefully shutdown the webservice application?

I'm using gSoap to write a webservice. It's running as a console application. In all gSoap examples I see, that requests are dispatched in infinite loop like for(;;;) even in multi-threaded version.
But how can I make my webservice to terminate gracefully when, say, user presses space on the console?
Preferably:
stop accepting new connections;
Serve existing ones;
Exit from application
The only solution I came up so far is using timeouts
soap->recv_timeout = 20;
soap->send_timeout = 20;
soap->connect_timeout = 5;
soap->accept_timeout = 5;
Then all blocking functions return periodically. But this is not ideal for me, because I want to be able to terminate the app quickly even if there is an ongoing transmission, but at the same time, don't want to compromise reliability on a slow/flaky connection (it's an embedded device connected via GPRS).
The section 7.2.4 How to Create a Multi-Threaded Stand-Alone Service in the documentation has example code for writing an accept loop. You need to write your own accept loop and add signal handling so it responds to Ctrl-C.
stop accepting new connections:
Leave the loop so you stop calling accept.
Serve existing ones:
The threads need to inform you when they are finished, so you can exit when the number of active clients is zero. (boost::thead_group has a join_all which does exactly that.)
Exit from application:
What you need to do is register signal handler so when you terminate your application using Ctrl + C, it calls you registered function where you can gracefully terminates.
e.g
class gsoap_test {
public:
void start() {
running_ = true;
while(running_) {
//gsoap threads
}
//stop and cleanup
}
void stop() {
running_ = false;
}
private:
bool running_;
};
//global variable
gsoap_test gsoap;
void sighandler(int sig)
{
std::cout<< "Signal caught..." << std::endl;
//Stop gracefully here
gsoap.stop();
exit(0);
}
int main(int argc, char** argv) {
//register signal
signal(SIGABRT, &sighandler);
signal(SIGTERM, &sighandler);
signal(SIGINT, &sighandler);
gsoap.start();
return EXIT_SUCCESS;
}

Boost Thread Hanging on _endthreadex

I think I am making a simple mistake, but since I noticed there are many boost experts here, I thought I would ask for help.
I am trying to use boost threads(1_40) on windows xp. The main program loads a dll, starts the thread like so (note this is not in a class, the static does not mean static to a class but private to the file).
static boost::thread network_thread;
static bool quit = false;
HANDLE quitEvent;
//some code omitted for clarity, ask if you think it would help
void network_start()
{
HANDLE *waitHandles = (HANDLE*)malloc(3 * sizeof(HANDLE));
waitHandles[0] = quitEvent;
waitHandles[1] = recvEvent;
waitHandles[2] = pendingEvent;
do {
//read network stuff, or quit event
dwEvents =WaitForMultipleObjects(3, waitHandles, FALSE, timeout);
} while (!quit)
}
DllClass::InitInstance()
{
}
DllClass::ExportedFunction()
{
network_thread = boost::thread(boost::bind<void>(network_start));
}
DllClass::ExitInstance()
{
//signal quit (which works)
quit = true;
SetEvent(QuitEvent);
//the following code is slightly verbose because I'm trying to figure out what's wrong
try {
if (network_thread.joinable() ) {
network_thread.join();
} else {
TRACE("Too late!");
}
} catch (boost::thread_interrupted&) {
TRACE("NET INTERRUPTED");
}
}
The problem is that the main thread is hanging on the join, and the network thread is hanging at the end of _endthreadex. What am I misunderstanding?
You are not supposed to create/end threads in InitInstance/ExitInstance,
see http://support.microsoft.com/default.aspx?scid=kb;EN-US;142243 for more info. Also, see http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx about DllMain in general.