c++ win 32 application . VS 2013
I am making use of a 3rd party library.
I want to call 3rd party library's function in a background thread.
I then also want to eventually turn it off.
I suspect I dont give third party enough time to properly shut itself down before I exist the application.
How do I ensure the detached task I started on a separate thread is done before I exit the main().
//this class interfaces with the third part and runs on a separate thread
class ThirdParty
{
void Start(std::string filename)
{
MyApplication application;
FIX::SessionSettings settings(filename);
FIX::FileStoreFactory storeFactory(settings);
FIX::ScreenLogFactory logFactory(settings);
FIX::SocketAcceptor acceptor(application, storeFactory, settings, logFactory);
acceptor.start(); //this third party internally starts new threads and does stuff thats transparent to consumer like myself.
while (m_runEngine)
{}
//this shutsdown a few things and cant execute instantaneously
//This does not finish execution and main() already ends.
acceptor.stop();
}
void Stop()
{
m_runEngine = false;
}
private:
bool m_runEngine{ true };
}
Here is my main() in a win32 application
int _tmain(int argc, _TCHAR* argv[])
{
std::wstring arg = argv[1];
std::string filename = std::string(arg.begin(), arg.end());
ThirdParty myprocess;
std::thread t(&ThirdParty::Start, &myprocess, filename);
t.detach();
while (true)
{
std::string value;
std::cin >> value;
if (value == "quit")
break;
}
myprocess.Stop(); //This line will execute really fast and application will exit without allowing acceptor.stop() to properly finish execution
//How can I ensure acceptor.stop() has finished execution before I move on to the next line and finish the application
return 0;
}
Do not make you thread detached, so that you can wait for it to end using thread::join():
//t.detach() do not detach thread
...
myprocess.Stop();
t.join(); // wait for t to end
I think the following example illustrates the interesting aspects of thread join.
void pause_thread(int n, std::string lbl)
{
std::this_thread::sleep_for (std::chrono::seconds(n));
std::cout << lbl << " pause of " << n << " seconds ended" << std::endl;
}
int t403(void) // in context of thread main
{
std::cout << "Spawning 3 threads...\n" << std::flush;
std::thread t1 (pause_thread, 3, "t1");
std::thread t2 (pause_thread, 2, "t2");
std::thread t3 (pause_thread, 1, "t3");
std::cout << "Done spawning threads, "
"Note that the threads finish out-of-order. \n"
"Now 'main' thread waits for spawned threads to join:\n" << std::flush;
t1.join(); std::cout << "join t1 " << std::flush;
t2.join(); std::cout << "join t2 " << std::flush;
t3.join(); std::cout << "join t3 " << std::flush;
std::cout << "completed join \n"
"note: \n - join sequence is in-order, but finish sequence is out-of-order\n"
" - inference: the threads waited in join main. "<< std::endl;
return(0);
}
Note that the threads are spawned in order: t1, t2, t3.
Note that the threads end in a different order.
But the join is still in the launch order, because that is what main waits for.
Using 'std::flush()' presents the timeline that has been chosen slow enough for human vision.
Related
i'm having trouble with some threads in my program
I'm new in this thread material
I'm trying to start 2 threads on 2 different object function and it seems that they are not working at the same time (t1 works and t2 dont)..
edit:
the function of t1 works but t2 doesnt work. i checked t2 and t1, on their own they work, but together its like t1 prevents t2 from working
here is the main:
MessagesSender MSM=MessagesSender();
MSM.Push_user("ronik");
MSM.Push_user("ligal");
thread t1(&MessagesSender::DataRead,&MSM);
thread t2(&MessagesSender::DataSend, &MSM);
t1.join();
t2.join();
return 0;
here are is the function of t1:
void MessagesSender::DataRead()
{
ifstream file_read;
ofstream file_delete;
string line;
while (true)
{
file_read.open("data.txt"); // opens the file
mtx.lock(); // locks the use of THOR
while (getline(file_read, line)) // reads to THOR
{
cout << "im reading now" << endl;
this->THOR.push(line);
}
mtx.unlock(); // unlock the use of THOR
file_read.close(); // closes the file for reading
file_delete.open("data.txt", ios::out | ios::trunc);/// opens the file and deletes the content/data
file_delete.close(); // closes the file
cout << "im sleeping now" << endl;
print_THOR();
this_thread::sleep_for(chrono::seconds(30)); // makes the thread sleep for 1 minute
}
}
here is the function of t2:
void MessagesSender::DataSend()
{
ofstream file_send;
file_send.open("output.txt");
set<string>::iterator SEI;
while (true)
{
mtx.lock();
while (!THOR.empty()) // while that prints all the THOR lines
{
for (SEI = ConUsers.begin(); SEI != ConUsers.end(); SEI++) /// to print the users
{
if (THOR.empty())
{
break;
}
string p2(THOR.front());
cout << "im sending now" << endl;
file_send << *SEI << ": " << p2 << endl;
}
}
mtx.unlock();
THOR.push("im empty");
print_THOR();
this_thread::sleep_for(chrono::seconds(30));
}
file_send.close();
}
I believe this may be an issue of buffered streams. You are using the std::cout and calling std::endl. This causes the thread to pause until the data has been written to the console (slow). I've done this before and had the same problem. t2 is getting hung up on the buffered stream, waiting for it to be cleared while t1 has used it. Try replacing your std::endl with regular '\n' then just do a std::cout << std::flush; at the end of your program.
I am working in a C++ DLL module where I need to perform a task for every X min independently. I tried to create a thread for the task but my main program which creates threads will also keep waiting for the child thread(s) to complete.
Could someone please help me how to create a separate process (Please provide sample code if possible) independent of main program and do the Task?
The process should take a function and run the code present in function for every X min.
EDIT:
void test(void *param)
{
cout << "In thread function" << endl;
Sleep(1000); // sleep for 1 second
cout << "Thread function ends" << endl;
_endthread();
}
int main()
{
HANDLE hThread;
cout << "Starting thread" << endl;
cout << (hThread = (HANDLE)_beginthread(test,0,NULL));
WaitForSingleObject( hThread, INFINITE );
cout << "Main ends" << endl;
return 0;
}
WaitForSingleObject() will block main until the thread completes. If you want to run some stuff periodically from the thread function test() you'll need to put a loop there. Best with some condition to trigger ending the thread function from main() when exiting. You shouldn't call WaitForSingleObject() before you want to exit the main() method. Thus you'll have the test() method running asynchonously.
bool endThread = false;
void test(void *param)
{
cout << "In thread function" << endl;
while(!endThread)
{
Sleep(1000); // sleep for 1 second
}
cout << "Thread function ends" << endl;
_endthread();
}
int main()
{
HANDLE hThread;
cout << "Starting thread" << endl;
cout << (hThread = (HANDLE)_beginthread(test,0,NULL));
// Do any other stuff without waiting for the thread to end
// ...
endThread = true;
WaitForSingleObject( hThread, INFINITE );
cout << "Main ends" << endl;
return 0;
}
Note that you might need to synchronize access to the endThread variable properly using a mutex or similar, the sample should just show the principle.
UPDATE:
In case you want to exit main() before the thread ends, you cannot use threads at all.
You'll need to create an independent child process as I had mentioned in my 1st comment. Lookup for the fork() and exec() functions to do this (there might be specific WinAPI methods for these also, I don't know about).
Is it possible to create a boost::thread and run it in the background (as a daemon)?
I am trying to the following but my thread dies when main exits.
/*
* Create a simple function which writes to the console as a background thread.
*/
void countDown(int counter) {
do {
cout << "[" << counter << "]" << endl;
boost::this_thread::sleep(seconds(1));
}while(counter-- > 0);
}
int main() {
boost::thread t(&countDown, 10);
if(t.joinable()) {
cout << "Detaching thread" << endl;
t.detach(); //detach it so it runs even after main exits.
}
cout << "Main thread sleeping for a while" << endl;
boost::this_thread::sleep(seconds(2));
cout << "Exiting main" << endl;
return 0;
}
[rajat#localhost threads]$ ./a.out
Detaching thread
Main thread sleeping for a while
[10]
[9]
Exiting main
[rajat#localhost threads]$
When your main() exits all other threads of the process are terminated (assuming Linux, can't say for Windows).
Why not just join() that background thread at the end of the main()? Or even better - use the main thread as the "daemon" thread?
I have blocking task which will be performed by find_the_question() function. However, I do not want thread executing this function take more than 10 seconds. So in case it takes more than 10 seconds, I want to close that thread with cleaning all the resources.
I tried to write a code for that, but somehow I am not able to get a interrupt in find_the_question() function if thread takes more than 10 seconds. Could you please tell me what am I doing wrong?
void find_the_question(std::string value)
{
//allocate x resources
try{
//do some process on resources
sleep(14);
//clean resources
}
catch(boost::thread_interrupted const& )
{
//clean resources
std::cout << "Worker thread interrupted" << std::endl;
}
}
int main()
{
boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(10000);
std::cout << "In main" << std::endl;
boost::thread t1(find_the_question, "Can you block me");
t1.interrupt();
if (t1.timed_join(timeout))
{
//finished
std::cout << "Worker thread finished" << std::endl;
}
else
{
//Not finished;
std::cout << "Worker thread not finished" << std::endl;
}
std::cout << "In main end" << std::endl;
}
Output:
If t1 takes more than 10 seconds to complete, I am getting following console output.
std::cout << "In main" << std::endl;
std::cout << "Worker thread not finished" << std::endl;
std::cout << "In main end" << std::endl;
whereas, I am expecting following output
std::cout << "In main" << std::endl;
std::cout << "Worker thread interrupted" << std::endl;
std::cout << "Worker thread not finished" << std::endl;
std::cout << "In main end" << std::endl;
Could you please tell me what am I doing wrong.
Thanks in advance
For using boost::thread::interrupt(), you have to use boost::thread::sleep() for it to work.
A running thread can be interrupted by invoking the interrupt() member
function of the corresponding boost::thread object. When the
interrupted thread next executes one of the specified interruption
points (or if it is currently blocked whilst executing one) with
interruption enabled, then a boost::thread_interrupted exception will
be thrown in the interrupted thread. If not caught, this will cause
the execution of the interrupted thread to terminate. As with any
other exception, the stack will be unwound, and destructors for
objects of automatic storage duration will be executed
Predefined interruption points:
The following functions are interruption points, which will throw
boost::thread_interrupted if interruption is enabled for the current
thread, and interruption is requested for the current thread:
boost::thread::join()
boost::thread::timed_join()
boost::condition_variable::wait()
boost::condition_variable::timed_wait()
boost::condition_variable_any::wait()
boost::condition_variable_any::timed_wait()
boost::thread::sleep()
boost::this_thread::sleep()
boost::this_thread::interruption_point()
In Java, I would do something like:
Thread t = new MyThread();
t.start();
I start thread by calling start() method. So later I can do something like:
for (int i = 0; i < limit; ++i)
{
Thread t = new MyThread();
t.start();
}
To create a group of threads and execute the code in run() method.
However, in C++, there's no such thing as start() method. Using Boost, if I want a thread to start running, I have to call the join() method in order to make a thread running.
#include <iostream>
#include <boost/thread.hpp>
class Worker
{
public:
Worker()
{
// the thread is not-a-thread until we call start()
}
void start(int N)
{
m_Thread = boost::thread(&Worker::processQueue, this, N);
}
void join()
{
m_Thread.join();
}
void processQueue(unsigned N)
{
float ms = N * 1e3;
boost::posix_time::milliseconds workTime(ms);
std::cout << "Worker: started, will work for "
<< ms << "ms"
<< std::endl;
// We're busy, honest!
boost::this_thread::sleep(workTime);
std::cout << "Worker: completed" << std::endl;
}
private:
boost::thread m_Thread;
};
int main(int argc, char* argv[])
{
std::cout << "main: startup" << std::endl;
Worker worker, w2, w3, w5;
worker.start(3);
w2.start(3);
w3.start(3);
w5.start(3);
worker.join();
w2.join();
w3.join();
w5.join();
for (int i = 0; i < 100; ++i)
{
Worker w;
w.start(3);
w.join();
}
//std::cout << "main: waiting for thread" << std::endl;
std::cout << "main: done" << std::endl;
return 0;
}
On the code above, the for loop to create 100 threads, normally I must use a boost::thread_group to add the thread function, and finally run all with join_all(). However, I don't know how to do it with thread function putting in a class which uses various class members.
On the other hand, the loop above will not behave like the loop in Java. It will make each thread execute sequentially, not all at once like the other separated threads, whose own join() is called.
What is join() in Boost exactly? Also please help me to create a group of threads which share the same class.
join doesn't start the thread, it blocks you until the thread you're joining finishes. You use it when you need to wait for the thread you started to finish its run (for example - if it computes something and you need the result).
What starts the thread is boost::thread, which creates the thread and calls the thread function you passed to it (in your case - Worker::processQueue).
The reason you had a problem with the loop is not because the threads didn't start, but because your main thread didn't wait for them to execute before finishing. I'm guessing you didn't see this problem in Java because of the scheduling differences, aka "undefined behavior". after edit In Java the threading behaves slightly differently, see the comment below for details. That explains why you didn't see it in Java.
Here's a question about the boost::thread_group. Read the code in the question and the answers, it will help you.
Joining a thread does the same thing in Boost as it does in Java: it waits for the thread to finish running.
Plus, if I remember correctly, Boost's threads run upon construction. You don't start them explicitly.