Choice between thread: time expired and user input - c++

I'm writing a simple function that, when called, allows to execute 2 different actions (exclusive).
So there are two threads. User_choice waits until the user inserts an input and the Time_choice waits until time expires.
The choice_done shared var says that, if true, one thread has already started and blocking (it doesn't do anything!) the other one; Whereas thread_done says, if true, that thread (it doesn't matter which) has already finished, so func() waits until one thread finishes.
Here is the code.
The func procedure will be called more times during the program execution.
The various user_choice thread will be waiting forever on getline! Is it a problem? What if, after four times the program will call func() and the user doesn't insert anything, the 5th time the user inserts "yes"?
Will every user_choice thread continue the execution?? How can I kill the waiting thread? Are there other solutions?
How can I wait inside func() that a thread sets thread_done to true?
bool choice_done = false;
bool thread_done = false;
void func(){
boost::thread t1(boost::bind( time_choice() ));
boost::thread t2(boost::bind( user_choice() ));
//whait untile thread_done == true
do something...
}
// Time choice thread
void time_choice(){
sleep(5);
if(choice_done == false){
printf("Automatic choice\n");
choice_done == true;
do something...
thread_done = true;
}
}
// User choice thread
void user_choice(){
printf("Start emergency procedure?\n");
string tmp;
getline(cin, tmp);
if((tmp.compare("yes") == 0) && (choice_done == false)){
printf("Manual choice\n");
choice_done == true;
do something...
thread_done = true;
}
}

Having to create a thread for a timer is generally a sign of sub-optimal design. It does not scale well (imagine thousands of timers) and the code gets multi-threaded and more complex for no good reason. Also, sleep is not thread-safe on Linux.
Just use one thread with select and a timeout. select will wait on STDIN_FILENO for user input and timeout simultaneously.
Or, better, use a 3rd-party event-demultiplexing library, like libevent or boost::asio.

Related

Kill an std::thread that wasn't joined

So I have a thread that I was running using .join() but I needed an interactive user interface while running the thread so I stopped using join because it halted the program while it ran. The ui has a stop button to kill the thread and now I need a way to stop the thread without killing the whole program because I can't use .detach(). Thanks!
There is no safe way to unilaterally terminate a thread. Instead, the thread's code must periodically check whether the GUI thread has requested that it exit.
I'm not familiar with the new C++ library functions, but I believe you can do this with atomic_bool, e.g., see this question.
you could pass a reference to a bool variable to the thread and check if it is true. if it is, return from the thread.
Example:
bool terminate = false;
std::mutex m;
std::thread t([&terminate,&m] {
std::unique_lock<std::mutex> lm{m,std::defer_lock}; //don't lock yet
int i = 0;
while (true) {
lm.lock(); //protect terminate -> no race conditions
if (terminate)
return;
lm.unlock(); //release lock for terminate
//do what your thread should do
std::cout << i++ << std::endl;
}
});
/*
do something else here
*/
m.lock();
terminate = true;
m.unlock();
t.join();

How to abort async() if timeout has elapsed

I have a questions about async() function or any other way to solve my problem. I send to the server specified type of message and I wait for a specific
response.
I have function receive() which waits for response from server. I call this function inside async().
Sample of code:
while (true) {
future_receive = std::async(std::launch::async, [&] {
receive();
});
do {
status = future_receive.wait_for(chrono::seconds(timeLimit));
if (status == std::future_status::timeout){
//if timeout, abort async() function
}
} while (status != std::future_status::ready);
}
What is my problem? In this case, if I get "timeout", async() function will work on,
will wait until something comes, even if it will never come, and in the next cycle will be called again,
and new thread will be created. How to avoid this?
How I can abort async() when "timeout" has elapsed. Maybe any other way without async() to solve this problem. I would like to use only the standard library of C++?
The asynchronous thread has to cooperate and check whether it should continue working or give up, there is no portable way to force it to stop without its cooperation.
One way to do that is to replace the receive() call with a similar one that has a timeout, and have the thread give up after a timeout, or check a flag after a timeout to indicate whether to continue.
while (true) {
std::atomic<bool> stop{false};
future_receive = std::async(std::launch::async, [&] {
while (!stop)
try_receive(std::chrono::seconds(1));
});
do {
status = future_receive.wait_for(chrono::seconds(timeLimit));
if (status == std::future_status::timeout){
stop = true;
}
} while (status != std::future_status::ready);
}
Now the asynchronous thread will only block for up to a second, then will check if it's been told to give up, otherwise it will try receiving again.
If you're willing to sacrifice portability, something like this should work on platforms where std::thread is implemented in terms of POSIX threads:
while (true) {
std::atomic<pthread_t> tid{ pthread_self() };
future_receive = std::async(std::launch::async, [&] {
tid = pthread_self();
receive();
});
do {
status = future_receive.wait_for(chrono::seconds(timeLimit));
if (status == std::future_status::timeout){
while (tid == pthread_self())
{ /* wait for async thread to update tid */ }
pthread_cancel(tid);
}
} while (status != std::future_status::ready);
}
This assumes that there is a Pthreads cancellation point somewhere in the receive() call, so that the pthread_cancel will interrupt it.
(This is slightly more complicated than I would like. It's necessary to store some known value in the atomic initially in order to handle the situation where the async thread has not even started running yet when the calling thread gets a timeout and tries to cancel it. To handle that I store the calling thread's ID, then wait until it's changed before calling pthread_cancel.)

Timing inconsistency with killing thread using event

I have a multithreaded C++ Windows application. The worker thread is an infinite loop waiting for events to process, one of which is a kill thread event from main thread. The problem is that sometimes it takes a really long time (think seconds) for the worker thread to receive the kill event and terminate. Other times it's very quick (milliseconds).
// Main thread code
void deactivate()
{
while (isWorkerThreadRunning)
{
// Problem: sometimes it spends a long time in this loop
logDebug("deactivate: killing worker thread");
SetEvent(killWorker);
Sleep(20);
}
}
// Worker thread code
DWORD WINAPI WorkerThreadProc(LPVOID arglist)
{
isWorkerThreadRunning = true;
logDebug("Worker thread started");
for (bool done = false; done != true; )
{
HANDLE handles[3] = { killWorker, action1, action2 };
DWORD rc = WaitForMultipleObjects(3, handles, FALSE, INFINITE);
switch (rc)
{
case WAIT_OBJECT_0 + 0: done = true; break;
case WAIT_OBJECT_0 + 1: doAction1(); break;
case WAIT_OBJECT_0 + 2: doAction2(); break;
default: logWarn("Unhandled wait signal");
}
}
isWorkerThreadRunning = false;
logDebug("Worker thread killed");
return 0;
}
I believe that if the worker thread receives a kill event while it is busy inside doAction1() or doAction2() the kill event won't be received and processed until doAction1() or doAction2() is completed and returned. And if doAction1() or doAction2() takes a long time to return then the worker thread will take a long time to exit.
However, I have log points sprinkled throughout doAction1() and doAction2() but I don't see any of those log points in the log file. All I see are:
deactivate: killing worker thread
deactivate: killing worker thread
deactivate: killing worker thread
deactivate: killing worker thread
//....many more times
Worker thead killed
which means the worker thread is not doing any work but rather waiting inside the WaitForMultipleObjects() call.
The question is why is the WaitForMultipleObjects() call sometimes take a long time (and sometimes very quick) to signal the waiter of an event??
Would changing the timeout from INFINITE to some reasonable number fix this problem?
Thanks,
Your declaration of isWorkerThreadRunning should be volatile if it is not. You can get some strange behavior when the compiler optimizes the code if it is not volatile.
volatile bool isWorkerThreadRunning;
I would also suggest entry and exit messages in your doAction functions. That will make it clearer if you're still inside one of those functions when the exit signal is sent.

When is it more appropriate to use a pthread barrier instead of a condition wait and broadcast?

I am coding a telemetry system in C++ and have been having some difficulty syncing certain threads with the standard pthread_cond_timedwait and pthread_cond_broadcast.
The problem was that I needed some way for the function that was doing the broadcasting to know if another thread acted on the broadcast.
After some hearty searching I decided I might try using a barrier for the two threads instead. However, I still wanted the timeout functionality of the pthread_cond_timedwait.
Here is basically what I came up with: (However it feels excessive)
Listen Function: Checks for a period of milliseconds to see if an event is currently being triggered.
bool listen(uint8_t eventID, int timeout)
{
int waitCount = 0;
while(waitCount <= timeout)
{
globalEventID = eventID;
if(getUpdateFlag(eventID) == true)
{
pthread_barrier_wait(&barEvent);
return true;
}
threadSleep(); //blocks for 1 millisecond
++waitCount;
}
return false;
}
Trigger Function: Triggers an event for a period of milliseconds by setting an update flag for the triggering period
bool trigger(uint8_t eventID, int timeout)
int waitCount = 0;
while(waitCount <= timeout)
{
setUpdateFlag(eventID, true); //Sets the update flag to true
if(globalEventID == eventID)
{
pthread_barrier_wait(&barEvent);
return true;
}
threadSleep(); //blocks for 1 millisecond
++waitCount;
}
setUpdateFlag(eventID, false);
return false;
}
My questions: Is another way to share information with the broadcaster, or are barriers really the only efficient way? Also, is there another way of getting timeout functionality with barriers?
Based on your described problem:
Specifically, I am trying to let thread1 know that the message it is
waiting for has been parsed and stored in a global list by thread2,
and that thread2 can continue parsing and storing because thread1 will
now copy that message from the list ensuring that thread2 can
overwrite that message with a new version and not disrupt the
operations of thread1.
It sounds like your problem can be solved by having both threads alternately wait on the condition variable. Eg. in thread 1:
pthread_mutex_lock(&mutex);
while (!message_present)
pthread_cond_wait(&cond, &mutex);
copy_message();
message_present = 0;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
process_message();
and in thread 2:
parse_message();
pthread_mutex_lock(&mutex);
while (message_present)
pthread_cond_wait(&cond, &mutex);
store_message();
message_present = 1;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);

How to kill a MFC Thread?

I spawn a thread using AfxBeginThread which is just an infinite while loop:
UINT CMyClass::ThreadProc( LPVOID param )
{
while (TRUE)
{
// do stuff
}
return 1;
}
How do I kill off this thread in my class destructor?
I think something like
UINT CMyClass::ThreadProc( LPVOID param )
{
while (m_bKillThread)
{
// do stuff
}
return 1;
}
and then set m_bKillThread to FALSE in the destructor. But I still need to wait in the destructor until the thread is dead.
Actively killing the thread:
Use the return value of AfxBeginThread (CWinThread*) to get the thread handle (m_hThread) then pass that handle to the TerminateThread Win32 API. This is not a safe way to terminate threads though, so please read on.
Waiting for the thread to finish:
Use the return value of AfxBeginThread (CWinThread*) to get the member m_hThread, then use WaitForSingleObject(p->m_hThread, INFINITE); If this function returns WAIT_OBJECT_0, then the thread is finished. Instead of INFINITE you could also put the number of milliseconds to wait before a timeout happens. In this case WAIT_TIMEOUT will be returned.
Signaling to your thread that it should end:
Before doing the WaitForSingleObject just set some kind of flag that the thread should exit. Then in your main loop of the thread you would check for that bool value and break the infinite loop. In your destructor you would set this flag then do a WaitForSingleObject.
Even better ways:
If you need even more control you can use something like boost conditions.
BTW, About TerminateThread(), use it this way.
DWORD exit_code= NULL;
if (thread != NULL)
{
GetExitCodeThread(thread->m_hThread, &exit_code);
if(exit_code == STILL_ACTIVE)
{
::TerminateThread(thread->m_hThread, 0);
CloseHandle(thread->m_hThread);
}
thread->m_hThread = NULL;
thread = NULL;
}
First you have to start the thread in a way so MFC doesn't delete the thread object when it's finished, the default setting for MFC thread is to delete itself so you want to turn that off.
m_thread = AfxBeginThread(ThreadProc, this, THREAD_PRIORITY_NORMAL ,CREATE_SUSPENDED);
m_thread->m_bAutoDelete = FALSE;
m_thread->ResumeThread();
Now in the thread, you want a mechanism that the caller thread can send it a signal to end itself. There are multiple ways, one is the WaitForSingleObject to check the status of the signal or another way is to simply send this thread a message to end itself. This is graceful ending rather killing it.
While this thread is ending itself (= exiting the thread function, cleaning up), you can have the main thread wait on it to finish before it exits.
int wait = 2000 // seconds ( I am waiting for 2 seconds for worker to finish)
int dwRes = WaitForSingleObject( m_thread->m_hThread, wait);
switch (dwRes)
{
case WAIT_OBJECT_0:
TRACE( _T("worker thread just finished") ); break;
case WAIT_TIMEOUT:
TRACE( _T("timed out, worker thread is still busy") ); break;
}
Note setting m_bAutoDelete = FALSE above made it possible we still have a valid handle when thread finishes so we can wait on it. The last thing you want to do now is delete the CWinThread object to free its memory (since we took the responsibility to do that).
You must wait, until thread do all stuff.
if(WaitForSingleObject(thread_handle, INFINITE) == WAIT_OBJECT_0)
;//all right
else
;//report error
beware using TerminateThread function, this is very dangerous.