Fetching from std::queue is CPU intensive in a multithreaded environment - c++

Please have a look at the following multithreaded C++ pseudocode.( No C++11 )
Mutex mtx;
addToQueueFromManyThreads()
{
mtx.lock;
pushTowriteQueue();
mtx.unLock();
}
run()
{
std::string nextMessage = fetchNext();
while ( !nextMessage.empty() )
{
// writeToFile( nextMessage );
// (void)SchedYield();
nextMessage = fetchNext();
}
delay( 25 ms );
}
std::string CTraceFileWriterThread::fetchNext()
{
std::string message;
mtx.lock;
if( !writeQueue.empty() )
{
message = writeQueue.front();
writeQueue.pop();
}
mtx.unLock();
return message;
}
Not much difference with or without 'writeToFile' or 'SchedYield'.
I am running on a low priority thread
The whole process is being killed due to heavy CPU usage because of the above code
addToQueueFromManyThreads is called extensively by the application as there are a lot of messages to be logged every second
At this point, I am wondering if I am using the right data structure and I have tried everything I can and run out of options. Any help with what could be happening is appreciated.

The logic in run() is flawed. It effectively runs non-stop, checking over and over again whether there's a message in the queue to be had. If there isn't, what does it do? It checks again, in faint hope that a new message arrived in the last millisecond, or so. That's why you're driving the CPU load high. The fact that it spends most of the time with a locked mutex, preventing other execution threads, that want to add a new message to the queue, from locking the mutex, does not help either.
The textbook solution to correctly implement this is simply using a condition variable, and waiting on it. Condition variables existed before C++11, and are available in POSIX. This will put the execution thread to sleep, stopping all CPU activity, completely, until the condition variable gets signalled by the other execution thread, after adding a new message to the queue. You cannot fix this without using a condition variable, there are no other practical alternatives.
How to use a condition variable is explained in every C++ textbook that covers execution threads and POSIX, where I will direct you for more information, and examples, especially since the shown code is pseudocode. You should spend some time reviewing this material in order to understand and learn the correct way to use condition variables, and their semantics. Improper usage won't help, and will likely make things worse.

Related

How to manage multiple threads without making the user wait?

Sorry if this was worded poorly, I wasn't sure how to give an accurate description of what I wanted in the title. But basically my goal is to have the user input times and for the program to alert them when the time has passed. After the time has passed, the program looks for another time while allowing the user to input more times. Basically, it would look something like this:
void printTime(tm time) {
//sleep until time
cout << "it is " << time << endl;
lookForNextTime();
}
void lookForNextTime() {
//find earliest time
printTime(time);
}
int main() {
//create thread in lookForNextTime
while(true) {
//ask user to insert more times until they quit
}
}
So while the user is inserting more times, the other thread is waiting to print out the earliest scheduled time. If the user inputs a new time that is after the current scheduled time, there shouldn't be an issue. But what happens if they input a time that is meant to come before the next time?
This is the problem. Let's say the earliest scheduled time is a month from now. The user inputs a new time that is two weeks from now. So what do we do? Make another thread, I guess. But then the user wants to input a time next week. And then a time three days from now. And then a time tomorrow. And so on.
I'm new to multithreading, but surely it's not a good idea to just let all of these new threads be made without regulation, right? So how do we control it? And when it's time to remove a thread, we need to use .join, correct? Is there a way to implement join that doesn't require the user to wait for the time to pass and allows them to continue inputting more times without interruption?
Welcome to StackOverflow. I am fairly new to threading in C++ myself so I'm not familiar with the best libraries and techniques, but I can share at least a little about the basics I do know, and hopefully that gives you a feel of where to go from there.
If I understand correctly I believe you question mainly revolves around join() so I'll start there.
Calling join() is how you wait for a thread to join before moving on, but you don't have to do that as soon as you create one or it would be pretty pointless. You can let the thread go on its own merry way and it will end when it is done without any further input from the main thread (please correct me I am mistaken).
The important thing about join() is that you call it on all the threads to wait for them before exiting the program (or otherwise aborting them somehow, safely of course). Otherwise they will continue running even after main() returns and will cause issues when they try to access memory as they are no longer attached to a running process. Another potential use might be to have a few worker threads match up at certain checkpoints in a calculation to share results before grabbing the next chunk of work.
Hope that helps. I had a few more thoughts though that I thought I would share in case you or some future reader aren't familiar with some of the other concepts involved in this example.
You don't indicate whether you have an way in mind for keeping tracking of the times and sharing them between threads, so so I'll just throw out a quick tip:
Lock your buffer before you add or pop from it.
Doing so is important in order to avoid race conditions where one thread could be trying to pop something off while the other is adding and causing weird issues to arise, especially if you end up using something like set from the standard library which sorts and ensures you only have one copy of any given element upon insertion.
If you aren't familiar with locking mechanisms then you could find examples of using Mutexes and Semaphores in C++, or do a search for 'locking' or 'Synchronization Objects'. You may consider the humble Mutex from the standard library.
As far as actually creating the threads, a couple things come to mind. One thought is using thread pools. There are several libraries out there for handling threading pools, with one such example being Apple's open source Grand Central Dispatch (commonly known as libdispatch) which can be used on Linux for sure, but for Windows you would want to look up something else (I'm not that familiar with the Windows platform unfortunately). They manage the life cycles of the threads you are and are not using so they could potentially help. Again, being a bit new to this myself I'm not 100% sure that would be the best thing for you, especially since you have other parts of the project to work out still, but it may be worth looking in to.
Even without using thread pools (say you use pthreads) I don't think you need to worry too much about starting a bunch of threads on your own as long as you put some reasonable limit on it (how much is reasonable I'm not sure but if you check out Activity Monitor in macOS or Task Manager in Windows or TOP in Linux you will see that at any given time many programs on your machine may be rocking quite a few threads-right now I have 5090 threads running and 327 processes. That's about 15.5 threads per process. Some process go much higher than that).
Hope something in there helps.
Here is an example from what I understood you're trying to do using the standard library. Usually threading will be controlled through various std::mutex, std::conditional_variable, and related flags to achieve the desired affect. There are libraries that can simplify threading for more complex scenarios, most prominently boost::asio.
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <condition_variable>
#include <mutex>
bool spuriousWakeup = true;
bool timerSet = false;
bool terminated = false;
int timerSeconds = 0;
std::thread timerThread;
std::mutex timerMutex;
std::condition_variable timerWakeup;
void printTimeThreadFunc()
{
// thread spends most of the time sleeping from condition variable
while (!terminated){
std::unique_lock<std::mutex> lock(timerMutex);
if(timerSet){
// use condition variable to sleep for time, or wake up if new time is needed
if(timerWakeup.wait_for(lock, std::chrono::seconds(timerSeconds), []{return !spuriousWakeup;})){
std::cout << "setting new timer for " << timerSeconds << " seconds!" << std::endl;
}
else{
std::cout << "timer expired!" << std::endl;
// timer expired and there is no time to wait for
// so next time through we want to get the un-timed wait
// to wait indefinitely for a new time
timerSet = false;
}
}
else{
std::cout << "waiting for timer to be set!" << std::endl;
timerWakeup.wait(lock, []{return !spuriousWakeup;});
}
spuriousWakeup = true;
}
}
int main()
{
// timer thread will exist during program execution, and will
// be communicated with through mutex, condition variable, and flags.
timerThread = std::thread(printTimeThreadFunc);
while (!terminated){
// get input from user
std::string line;
std::getline(std::cin, line);
// provide a way to quit
if (line == "end") {
terminated = true;
break;
}
// make sure its a number
try{
// put scope on lock while we update variables
{
std::unique_lock<std::mutex> lock(timerMutex);
timerSet = true;
timerSeconds = std::stoi(line);
spuriousWakeup = false;
}
// let thread know to process new time
timerWakeup.notify_one();
}
catch (const std::invalid_argument& ia) {
std::cerr << "Not a integer" << ia.what() << '\n';
}
}
// clean up thread
if(terminated && timerThread.joinable()){
timerWakeup.notify_one();
timerThread.join();
}
}

Forcibly terminate method after a certain amount of time

Say I have a function whose prototype looks like this, belonging to class container_class:
std::vector<int> container_class::func(int param);
The function may or may not cause an infinite loop on certain inputs; it is impossible to tell which inputs will cause a success and which will cause an infinite loop. The function is in a library of which I do not have the source of and cannot modify (this is a bug and will be fixed in the next release in a few months, but for now I need a way to work around it), so solutions which modify the function or class will not work.
I've tried isolating the function using std::async and std::future, and using a while loop to constantly check the state of the thread:
container_class c();
long start = get_current_time(); //get the current time in ms
auto future = std::async(&container_class::func, &c, 2);
while(future.wait_for(0ms) != std::future_status::ready) {
if(get_current_time() - start > 1000) {
//forcibly terminate future
}
sleep(2);
}
This code has many problems. One is that I can't forcibly terminate the std::future object (and the thread that it represents).
At the far extreme, if I can't find any other solution, I can isolate the function in its own executable, run it, and then check its state and terminate it appropriately. However, I would rather not do this.
How can I accomplish this? Is there a better way than what I'm doing right now?
You are out of luck, sorry.
First off, C++ doesn't even guarantee you there will be a thread for future execution. Although it would be extremely hard (probably impossible) to implement all std::async guarantees in a single thread, there is no direct prohibition of that, and also, there is certainly no guarantee that there will be a thread per async call. Because of that, there is no way to cancel the async execution.
Second, there is no such way even in the lowest level of thread implementation. While pthread_cancel exists, it won't protect you from infinite loops not visiting cancellation points, for example.
You can not arbitrarily kill a thread in Posix, and C++ thread model is based on it. A process really can't be a scheduler of it's own threads, and while sometimes it is a pain, it is what it is.

A Simple pthread_create causing 100% CPU usage in Qt

When a simple Thread is run with just an infinite loop in it causing 100% CPU, how come is this possible?
My thread call is as follows on a QEvent in Qt dialog class, Say on a button click.
pthread_t thread_id;
pthread_create( &thread_id, NULL, DataCollectionThread, (void*) this );
And my thread procedure is,
void* DataCollectionThread( void* pParam )
{
((m_DataCollection*)pParam)->m_ReadDatafromport();
return NULL;
}
And this ReadData() contains...
while(1)
{
}
My requirement is collecting data from serial port and plot a graph continuously. But as the CPU usage is 100%, any hardware interrupt in between plotting cause the plotting to stall, as the CPU switches the task to handle interrupt.
I am calling this thread in a Qt::Dialog based class. I am pretty sure that nothing other than this is triggered. What's wrong with this? Does a simple infinite loop causes 100% CPU consumption eh? Or Is there any problem with using pthread_create in Qt?
EDIT:For Jonathon Reinhart
This is the actual while loop
while( 1 )
{
while(( Dataisavailable))
{
//push the read data to stack
}
if(!m_DataReadable)
break;
}
Unlike cooperative multitasking, true OS-supported threads allow the CPU to interrupt code that's locked like this. So your computer isn't completely dying. But some degradation will occur. The computer doesn't have a good way of knowing not to try its best to run the code it's given if there is work to do...short of scheduling tools like nice
Sometimes you can mitigate the problems caused by something like this with "thread priorities". Qt has a QThread::setPriority() abstraction but note that it says:
The effect of the priority parameter is dependent on the operating system's scheduling policy. In particular, the priority will be ignored on systems that do not support thread priorities (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler for more details).
Seems the Qt people looked at thread priorities under linux and gave up. So if that's your platform, then you likely should just design your system so it doesn't spin like this.
I'd be curious what happened if you change ReadData() to...
QMutex dummy;
while(1)
{
QMutexLocker locker (&dummy);
}
(which was my way of trying something that may be more effectively done with the sched_yield that #jweyrich just mentioned.)
One simple hack to get around this: Go to sleep for (short) periods to let the CPU do other stuff. #include <ctime> and add somewhere in your loop:
struct timespec ts;
ts.tv_sec=0;
ts.tv_nsec=10000000; // 10 milliseconds
nanosleep(&ts, NULL);
Of course, it would be better if you could explicitly sleep until you have actual work to do (more input to read, a full queue to trim). But adding in short sleeps will probably be sufficient.
It might make sense to look into your m_pDataProvider object's implementation. Check for or add a method allowing you to sleep until there's more data. If you're just reading from a character device (e.g. ttyS0), poll or select might be useful here.
YES.
while(1) { }
Is going to do the following:
1. Does the number 1 equate to true?
2. Yes.
3. Go to 1.
The CPU is going to continuously do this whenever that thread is executing. Why are you starting a thread just to put it in a spin loop that does nothing?

Synchronizing looping threads

I am making some multi-threaded video game code. Before I began coding I looked at an article describing vaguely Valve's solution to multi-threaded game design. A key concept I gleaned from the article is thread synchronization. I don't know if this is how Valve does it but I imagined multiple threads each executing a game loop. At the end of each iteration, the threads pause and wait for other threads to finish their current iteration, then synchronize shared data. I figure that besides the overhead is this management scheme, there would be no different to just let the threads operate completely asynchronously. The article mentioned a thread used exclusively for syncing but I am trying to get a different solution to work correctly. This is how I (try) to do it:
// at end of loop on each thread...
sig_thread_done();
while (!is_sync_done())
{
PauseExecution(1);
}
sig_thread_done and is_sync_done are function objects from another class that controls a list of all "threads". These functions look like this:
bool Core::IsFrameDone()
{
MutexLock lock(manager_mutex);
if (waiting_components == -1)
{
waiting_components = 0;
return true;
}
return false;
}
void Core::SignalFrameDone()
{
MutexLock lock(manager_mutex);
if (++waiting_components == (int)components.size()) // components == threads
{
//sync shared data...
waiting_components = -1; // -1 signifies that all threads have completed their iteration
}
}
The problem is that a fast thread can exit its waiting loop and come back around to it again before other threads have a chance to exit there's. So the other threads miss the exit through is_sync_done returning false before another thread begins waiting and the whole system gets stuck waiting forever.
I can't find an easy way to resolve this issue. I really like this approach because synchronization doesn't get stalled while some independent thread performs the sync.
I appreciate any insight or suggestions anyone has to offer.
Link to article.
I think you are trying to re-invent a Thread barrier.
For something like this you want to sync on a barrier, with something like a Win32 Event (or an array thereof), this makes sure you cannot get the situation you described (the barrier ensures that everything syncs up to the same frame) while at the same time freeing CPU time, as waiting on events is done as a kernel signal, and sleeps the thread till that signal is received. You'd also what to use wait-free algorithms in there, these work particularly well if you have a job/task based threading model, where certain things can be decoupled from the system.
Also, here is a better publication on multi-threading the source engine, its far more in depth and technical (they also specifically state that they avoid mutexes for this sort of thing).

What is the best way to wait for a variable in a multithreaded application

I would like to do something like the below for a multi-threaded program:
// wait for variable to become true but don't hog resources
// then re-sync queues
Is something like this a good solution?
while (!ready) {
Thread.Sleep(250); // pause for 1/4 second;
};
No, this is not a good solution. First it might sleep too long. Second it's easy for threads to get into lockstep. Here's couple of links to MSDN articles on proper synchronization techniques:
Conditional variables
Events
Here's how you do it using boost:
boost::condition_variable condvar;
boost::mutex mutex;
bool finished1 = false;
bool finished2 = false;
void longComputation1()
{
{
boost::lock_guard<boost::mutex> lock(mutex);
finished1 = false;
}
// Perform long computation
{
boost::lock_guard<boost::mutex> lock(mutex);
finished1 = true;
}
condvar.notify_one();
}
void longComputation2()
{
{
boost::lock_guard<boost::mutex> lock(mutex);
finished2 = false;
}
// Perform long computation
{
boost::lock_guard<boost::mutex> lock(mutex);
finished2 = true;
}
condvar.notify_one();
}
void somefunction()
{
// Wait for long computations to finish without "spinning"
boost::lock_guard<boost::mutex> lock(mutex);
while(!finished1 && !finished2)
{
condvar.wait(lock);
}
// Computations are finished
}
For the sake of brevity, I didn't include the thread spawning code.
The boost::lock_guard uses the RAII idiom to automatically unlock the mutex when the lock object goes out of scope. Very useful for preventing deadlocks in case of exceptions.
I find condition variables less error prone than Microsoft's Event objects. If you use boost.Thread, you'll have the added benefit of cross-platform potability.
Try to use Event (kernel object) instead of simple variable and replace your loop by:
WaitForSingleObject(hEventHandle, INFINITE);
The code above will work, and maybe appropriate in some circumstances.
You could also look at a critical section or semaphore - this will make your application block and wait until the resource becomes available,
Your thread that does the work grabs the mutex, does some work, meanwhile, the main method also tries to grab the same mutex, but can't. when the worker thread(s) exit, they release the mutex and your main thread can pass the critical section and continue.
First of all, you need to declare your 'ready' variable at least 'volatile' or this could have nasty side effects. Secondly, sleeping that long vefore reevaluating the condition is only a good idea if the duration it might take is indeed very long, let's say a few minutes.
Using the WinAPI's Event functions (CreateEvent, SetEvent(), WaitForSingleEvent()) is the best way to do it. Of course it introduces some overhead, but usually it's fine.
If you want to stick with your solution, looping and rechecking the condition a few times before you sleep again could improve performance in some scenarios.
The raw Win32 API has EVENT for doing this, here's a usage example:
http://msdn.microsoft.com/en-us/library/ms686915(VS.85).aspx
However, that API is C-oriented and particular to Windows. If writing a C++ program you might consider making your code more platform independent by using something like boost::threads, which has an analogue in Conditions.
A caveat I've found is that Windows can WaitForMultipleObjects, thus waiting on several events (and other handle classes) at a time. boost has no parallel AFAIK.
On top of good answers already provided - you will waste half the sleep time, assuming a random distribution of the occurrence you wish to detect. 125ms is an eternity in computer time.
WaitForSingleObject on a Win32 Event handle allows you to detect the required signal pseudo-immediately (depending on what other threads in your process are doing), and not do redundant checks (how many needless loops do you have to execute before the signal arrives?), provided the setting thread call SetEvent once it's done with its work. The bool is then redundant, which is as it should be.
Granted this is C#, but I've found this book to be extremely helpful for doing multi-threading development.
http://www.albahari.com/threading/
Some of the info is not language specific.