Not strictly related to C++, I am looking for more of a design patter or suggestion on how to approach this.
Say I have
class A
{
public:
void process();
void wait();
}
I will first call process(), which (duuh) does some processing and will then call wait(). The wait() function is supposed to wait for a notification and then exit. I already have the logic for the notification on a separate thread, but I'm not really sure what the best approach for this is.
What I thought of is:
void A::wait()
{
while ( _notificationOccured == false )
{
}
}
where _notificationOccured can be a bool member of A that will be changed by the notification. But, again, I'm not sure that this is the best approach. Any suggestions?
Pooling for a variable gives terrible performance, because pooling thread takes almost all CPU time. You need to use events or messages - this stuff is platform-specific. You can use some portable library for this, for example, Boost.
What you do is called busy waiting.
The are various techniques to do this better, the simplest would be to use a plain mutex with ncondition notification (win32/pthreads/boost).
Your current approach introduces a power-loop, which will kill the performance of the system you are running on. You should introduce a short sleep-time (10ms will suffice) to prevent that from happening. Better yet, use a library, like Boost (as #Nim suggested).
Btw, polling like you do is not all bad. In fact, that is what so-called spin-locks do. The idea is that a short time of polling is more efficient than locking if the expected wait-time is short.
Two options:
Semaphores
Conditions
Both are OS specific, boost has support for latter. There are other ways (such as atomic operations, but how these are exposed is compiler specific). IMHO, I would use one of the above.
I only know this from Windows, so I don't know if this translates easily to other plattforms.
In pseudo code:
Timer myTimer(1, MYEVENT); // elapses every second
SetTimer( myTimer ); // register timer with event loop
while( running )
{
if( GetEvent() == MYEVENT )
{
}
}
In Windows GetEvent() is called WaitForSingleObject(...)
Related
Following on from this question, I'd like to know what's the recommended approach we should take to replace the very common pattern we have in legacy code.
We have plenty of places where a primary thread is spawing one or more background worker threads and periodically pumping out some work for them to do, using a suitably synchronized queue. So the general pattern for a worker thread will look like this:
There will be an event HANDLE and a bool defined somewhere (usually as member variables) -
HANDLE hDoSomething = CreateEvent(NULL, FALSE, FALSE, NULL);
volatile bool bEndThread = false;
Then the worker thread function waits for the event to be signalled before doing work, but checks for a termination request inside the main loop -
unsigned int ThreadFunc(void *pParam)
{
// typical legacy implementation of a worker thread
while (true)
{
// wait for event
WaitForSingleObject(hDoSomething, INFINITE);
// check for termination request
if (bEndThread) break;
// ... do background work ...
}
// normal termination
return 0;
}
The primary thread can then give some work to the background thread like this -
// ... put some work on a synchronized queue ...
// pulse worker thread to do the work
SetEvent(hDoSomething);
And it can finally terminate the worker thread like so -
// to terminate the worker thread
bEndThread = true;
SetEvent(hDoSomething);
// wait for worker thread to die
WaitForSingleObject(hWorkerThreadHandle, dwSomeSuitableTimeOut);
In some cases, we've used two events (one for work, one for termination) and WaitForMultipleObjects instead, but the general pattern is the same.
So, looking at replacing the volatile bool with a C++11 standard equivalent, is it as simple as replacing this
volatile bool bEndThread = false;
with this?
std::atomic<bool> bEndThread = false;
I'm sure it will work, but it doesn't seem enough. Also, it doesn't affect the case where we use two events and no bool.
Note, I'm not intending to replace all this legacy stuff with the PPL and/or Concurrency Runtime equivalents because although we use these for new development, the legacy codebase is end-of-life and just needs to be compatible with the latest development tools (the original question I linked above shows where my concern arose).
Can someone give me a rough example of C++11 standard code we could use for this simple thread management pattern to rewrite our legacy code without too much refactoring?
If it ain't broken don't fix it (especially if this is a legacy code base)
VS style volatile will be around for a few more years. Given that
MFC isn't dead this won't be dead any time soon. A cursory Google
search says you can control it with /volatile:ms.
Atomics might do the job of volatile, especially if this is a counter
there might be little performance overhead.
Many Windows native functions have different performance characteristics when compared to their C++11 implementation. For example, Windows TimerQueues and Multimedia have precision that is not possible to achieve with C++11.
For example ::sleep_for(5)
will sleep for 15 (and not 5 or 6). This can be solved with a mysterious
call to timeSetPeriod. Another example is that unlocking on a condition variable can be slow to respond. Interfaces to fix these aren't exposed to C++11 on Windows.
I have several work functions, that call accessory functions that might have something bad happen. I want to be able to stop the work functions if an accessory function determines something bad happened, without putting numerous flag checks in the work functions. For example,
struct Worker {
bool badhappened = false;
Worker() {
std::thread([&]() {
while ( not badhappened );
// kill the work
}).detach();
}
int WorkComponent {
if ( badhappening() )
badhappened = true;
return someint;
}
void DoWork {
// WorkComponents called several times
}
}
But I don't know what to call at kill the work. It's not a problem for DoWork to happen in a separate thread, but there doesn't appear to be an equivalent pthread_kill in C++'s threads. Is there a solution that doesn't involve putting several if(badhappened) return; calls into DoWork?
Long story short:
There is no safe way to stop a non-cooperative thread.
Yes, there are tools to forcibly shut down a thread but you are asking for trouble. The only safe way is to agree on a termination policy. This boils down to checking a flag sufficiently frequently as you write.
More on this from the gurus:
C++ and Beyond 2011: Scott, Andrei and Herb - Ask Us Anything
See at 30:44 What's the deal with systematic and principled thread termination and program termination?
Canceling a thread is not a good idea in POSIX either:
Cancelling a thread using pthread_cancel : good practice or bad
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?
I'm programming in C++, but I'm only using pthread.h, no boost or C++11 threads.
So I'm trying to use threads but based on one of my previous questions (link), this doesn't seem feasible since threads terminate right after completion of its task, and one of the more prevalent reasons to use a thread-pool implementation is to reduce thread-creation overhead by reusing these threads for multiple tasks.
So is the only other way to implement this in C to use fork(), and create a pipe from the main to child processes? Or is there a way to set up a pipe between threads and their parent that I don't know about?
Many thanks in advance!
Yes, you can create a thread-safe queue between the threads. Then the threads in the pool will sit in a loop retrieving an item from the queue, executing whatever it needs, then going back and getting another.
That's generally a bit easier/simpler in C++ because it's a little easier to agree on some of the interface (e.g., overload operator() to execute the code for a task), but at a fundamental level you can do all the same things in C (e.g., each task struct you put in the queue will contain a pointer to a function to carry out the work for that task).
In your case, since you are using C++, it's probably easier to use an overload of operator() to do the work though. The rest of the task struct (or whatever you choose to call it) will contain any data needed, etc.
From the POSIX standard:
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);
(...) The thread is created executing start_routine with arg as its sole argument.
So, you should create a bunch of threads with this function, and have them all execute a function that goes something like
void *consumer(void *arg)
{
WorkQueue *queue = static_cast<WorkQueue *>(arg);
for (task in queue) {
if (task == STOP_WORKING)
break;
do work;
}
return WHATEVER;
}
(At the end of input, push n STOP_WORKING items to the queue where n is the number of threads.)
Mind you, pthreads is a very low-level API that offers very little type-safety (all data is passed as void pointers). If you're trying to parallelize CPU-intensive tasks, you might want to look at OpenMP instead.
'doesn't seem feasible since threads terminate right after completion of its task' what??
for(;;){
Task *myTask=theCommonProducerConsumerQueue->pop();
myTask->run();
}
.. never return anything, in fact, never return.
You may find it helpful to look at the source code for libdispatch, which is the basis for Apple's Grand Central Dispatch and uses thread pools.
I would suggest using Threaded Building Blocks from Intel to accomplish work-queue/threadpool like tasks. A fairly contrived example using TBB 3.0:
class PoorExampleTask : public tbb::task {
PoorExampleTask(int foo, tbb::concurrent_queue<float>& results)
: _bar(foo), _results(results)
{ }
tbb::task* execute() {
_results.push(pow(2.0, foo));
return NULL;
}
private:
int _bar;
tbb::concurrent_queue<float>& _results;
}
Used later on like so:
tbb::concurrent_queue<float> powers;
for (int ww = 0; ww < LotsOfWork; ++ww) {
PoorExampleTask* tt
= new (tbb::task::allocate_root()) PoorExampleTask(ww, powers);
tbb::task::enqueue(*tt);
}
http://people.clarkson.edu/~jmatthew/cs644.archive/cs644.fa2001/proj/locksmith/code/ExampleTest/threadpool.c
I used google a couple months ago, you should try it.
Edit: it seems maybe you want a group instead. I was able to create one with some minor alteration of the above so that the worker didn't perform work, but just joined threads.
I am currently trying to use boost::asio for some simple tcp networking for the first time, and I allready came across something I am not really sure how to deal with. As far as I understand io_service.run() method is basically a loop which runs until there is nothing more left to do, which means it will run until I release my little server object. Since I allready got some sort of mainloop set up, I would rather like to update the networking loop manually from there just for the sake of simplicity, and I think io_service.poll() would do what I want, sort of like this:
void myApplication::update()
{
myIoService.poll();
//do other stuff
}
This seems to work, but I am still wondering if there is a drawback from this method since that does not seem to be the common way to deal with boost::asios io services. Is this a valid approach or should I rather use io_service.run() in a non blocking extra thread?
Using io_service::poll instead of io_service::run is perfectly acceptable. The difference is explained in the documentation
The poll() function may also be used
to dispatch ready handlers, but
without blocking.
Note that io_service::run will block if there's any work left in the queue
The work class is used to inform the
io_service when work starts and
finishes. This ensures that the
io_service object's run() function
will not exit while work is underway,
and that it does exit when there is no
unfinished work remaining.
whereas io_service::poll does not exhibit this behavior, it just invokes ready handlers. Also note that you will need to invoke io_service::reset on any subsequent invocation to io_service:run or io_service::poll.
A drawback is that you'll make a busy loop.
while(true) {
myIoService.poll()
}
will use 100% cpu. myIoService.run() will use 0% cpu.
myIoService.run_one() might do what you want but it will block if there is nothing for it to do.
A loop like this lets you poll, doesn't busy-wait, and resets as needed. (I'm using the more recent io_context that replaced io_service.)
while (!exitCondition) {
if (ioContext.stopped()) {
ioContext.restart();
}
if (!ioContext.poll()) {
if (stuffToDo) {
doYourStuff();
} else {
std::this_thread::sleep_for(std::chrono::milliseconds(3));
}
}
}