How to manage multiple threads without making the user wait? - c++

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();
}
}

Related

Force program termination if threads block in C++

When a class is responsible for managing a thread, it is a common pattern (see for example here) to join this thread in the destructor after you have made sure that the thread will finish in time. However, this is not always trivial as outlined in the linked thread leading to a program that never terminates if done incorrectly. Given below is an example to reproduce such a situation:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
class Foo {
public:
Foo() {
mythread = std::thread([&](){
int i = 0;
while(running) {
std::cout << "hi" << std::endl;
if (i++ >= 2) {
// placeholder for e.g. a blocking condition variable
std::this_thread::sleep_for(1000h);
}
std::this_thread::sleep_for(500ms);
}
});
}
~Foo() {
running = false;
mythread.join();
}
private:
std::thread mythread;
bool running{true};
};
int main() {
Foo bar;
std::this_thread::sleep_for(1s);
// enabling this line will block the termination
//std::this_thread::sleep_for(2s);
std::cout << "ending" << std::endl;
}
What I am searching for is a solution that forcefully terminates the program if this situation occurs. Of course, one should always strive towards finishing the thread properly, but having such feature would be good as last resort to have a peace of mind, especially for unobserved embedded systems where crashing programs can be easier restored and debugged than blocking programs.
A rough solution draft would be to start a thread at the end of the main that sleeps for a few seconds and if the program has not ended after that time, std::terminate is called (and ideally a corresponding error is reported). However, we have a chicken-or-egg problem because this new thread will of course keep the program from ending in time. I would highly appreciate any ideas.
EDIT: The solution should not require modification of the Foo class itself so that it also covers respective bugs in unmodified code of e.g. external libraries. Ideally, it would even cover threads no class feels responsible for ending them before the main ends (classes with static storage duration or even no longer referenced objects with dynamic storage duration), but that might not be possible at all without in-depth OS hacking or an external process monitor.
There are several solutions:
Investigate and fix the root problem (this is the best and correct solution)
Workarounds:
You can notify from thread about exiting via condition variable. And only after it do join. If CV's wait_for returns with timeout - kill thread (bad solution, there are another problems).
You can create watch-thread, which will verify time-counter. Counter should be reset from time to time by the application. If watch-thread detects too high value in time-counter, it restarts whole the application.
Move suspicious code out of your application to separate process and communicate with it via IPC. In case of problems - restart that application (best among the workarounds)

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

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.

Shared file logging between threads in C++ 11 [duplicate]

This question already has answers here:
Is cout synchronized/thread-safe?
(4 answers)
Closed 5 years ago.
Recently I started learning C++ 11. I only studied C/C++ for a brief period of time when I was in college.I come from another ecosystem (web development) so as you can imagine I'm relatively new into C++.
At the moment I'm studying threads and how could accomplish logging from multiple threads with a single writer (file handle). So I wrote the following code based on tutorials and reading various articles.
My First question and request would be to point out any bad practices / mistakes that I have overlooked (although the code works with VC 2015).
Secondly and this is what is my main concern is that I'm not closing the file handle, and I'm not sure If that causes any issues. If it does when and how would be the most appropriate way to close it?
Lastly and correct me if I'm wrong I don't want to "pause" a thread while another thread is writing. I'm writing line by line each time. Is there any case that the output messes up at some point?
Thank you very much for your time, bellow is the source (currently for learning purposes everything is inside main.cpp).
#include <iostream>
#include <fstream>
#include <thread>
#include <string>
static const int THREADS_NUM = 8;
class Logger
{
public:
Logger(const std::string &path) : filePath(path)
{
this->logFile.open(this->filePath);
}
void write(const std::string &data)
{
this->logFile << data;
}
private:
std::ofstream logFile;
std::string filePath;
};
void spawnThread(int tid, std::shared_ptr<Logger> &logger)
{
std::cout << "Thread " + std::to_string(tid) + " started" << std::endl;
logger->write("Thread " + std::to_string(tid) + " was here!\n");
};
int main()
{
std::cout << "Master started" << std::endl;
std::thread threadPool[THREADS_NUM];
auto logger = std::make_shared<Logger>("test.log");
for (int i = 0; i < THREADS_NUM; ++i)
{
threadPool[i] = std::thread(spawnThread, i, logger);
threadPool[i].join();
}
return 0;
}
PS1: In this scenario there will always be only 1 file handle open for threads to log data.
PS2: The file handle ideally should close right before the program exits... Should it be done in Logger destructor?
UPDATE
The current output with 1000 threads is the following:
Thread 0 was here!
Thread 1 was here!
Thread 2 was here!
Thread 3 was here!
.
.
.
.
Thread 995 was here!
Thread 996 was here!
Thread 997 was here!
Thread 998 was here!
Thread 999 was here!
I don't see any garbage so far...
My First question and request would be to point out any bad practices / mistakes that I have overlooked (although the code works with VC 2015).
Subjective, but the code looks fine to me. Although you are not synchronizing threads (some std::mutex in logger would do the trick).
Also note that this:
std::thread threadPool[THREADS_NUM];
auto logger = std::make_shared<Logger>("test.log");
for (int i = 0; i < THREADS_NUM; ++i)
{
threadPool[i] = std::thread(spawnThread, i, logger);
threadPool[i].join();
}
is pointless. You create a thread, join it and then create a new one. I think this is what you are looking for:
std::vector<std::thread> threadPool;
auto logger = std::make_shared<Logger>("test.log");
// create all threads
for (int i = 0; i < THREADS_NUM; ++i)
threadPool.emplace_back(spawnThread, i, logger);
// after all are created join them
for (auto& th: threadPool)
th.join();
Now you create all threads and then wait for all of them. Not one by one.
Secondly and this is what is my main concern is that I'm not closing the file handle, and I'm not sure If that causes any issues. If it does when and how would be the most appropriate way to close it?
And when do you want to close it? After each write? That would be a redundant OS work with no real benefit. The file is supposed to be open through entire program's lifetime. Therefore there is no reason to close it manually at all. With graceful exit std::ofstream will call its destructor that closes the file. On non-graceful exit the os will close all remaining handles anyway.
Flushing a file's buffer (possibly after each write?) would be helpful though.
Lastly and correct me if I'm wrong I don't want to "pause" a thread while another thread is writing. I'm writing line by line each time. Is there any case that the output messes up at some point?
Yes, of course. You are not synchronizing writes to the file, the output might be garbage. You can actually easily check it yourself: spawn 10000 threads and run the code. It's very likely you will get a corrupted file.
There are many different synchronization mechanisms. But all of them are either lock-free or lock-based (or possibly a mix). Anyway a simple std::mutex (basic lock-based synchronization) in the logger class should be fine.
The first massive mistake is saying "it works with MSVC, I see no garbage", even moreso as it only works because your test code is broken (well it's not broken, but it's not concurrent, so of course it works fine).
But even if the code was concurrent, saying "I don't see anything wrong" is a terrible mistake. Multithreaded code is never correct unless you see something wrong, it is incorrect unless proven correct.
The goal of not blocking ("pausing") one thread while another is writing is unachieveable if you want correctness, at least if they concurrently write to the same descriptor. You must synchronize properly (call it any way you like, and use any method you like), or the behavior will be incorrect. Or worse, it will look correct for as long as you look at it, and it will behave wrong six months later when your most important customer uses it for a multi-million dollar project.
Under some operating systems, you can "cheat" and get away without synchronization as these offer syscalls that have atomicity guarantees (e.g. writev). That is however not what you may think, it is indeed heavyweight synchronization, only just you don't see it.
A better (more efficient) strategy than to use a mutex or use atomic writes might be to have a single consumer thread which writes to disk, and to push log tasks onto a concurrent queue from how many producer threads you like. This has minimum latency for threads that you don't want to block, and blocking where you don't care. Plus, you can coalesce several small writes into one.
Closing or not closing a file seems like a non-issue. After all, when the program exits, files are closed anyway. Well yes, except, there are three layers of caching (four actually if you count the physical disk's caches), two of them within your application and one within the operating system.
When data has made it at least into the OS buffers, all is good unless power fails unexpectedly. Not so for the other two levels of cache!
If your process dies unexpectedly, its memory will be released, which includes anything cached within iostream and anything cached within the CRT. So if you need any amount of reliability, you will either have to flush regularly (which is expensive), or use a different strategy. File mappying may be such a strategy because whatever you copy into the mapping is automatically (by definition) within the operating system's buffers, and unless power fails or the computer explodes, it will be written to disk.
That being said, there exist dozens of free and readily available logging libraries (such as e.g. spdlog) which do the job very well. There's really not much of a reason to reinvent this particular wheel.
Hello and welcome to the community!
A few comments on the code, and a few general tips on top of that.
Don't use native arrays if you do not absolutely have to.
Eliminating the native std::thread[] array and replacing it with an std::array would allow you to do a range based for loop which is the preferred way of iterating over things in C++. An std::vector would also work since you have to generate the thredas (which you can do with std::generate in combination with std::back_inserter)
Don't use smart pointers if you do not have specific memory management requirements, in this case a reference to a stack allocated logger would be fine (the logger would probably live for the duration of the program anyway, hence no need for explicit memory management). In C++ you try to use the stack as much as possible, dynamic memory allocation is slow in many ways and shared pointers introduce overhead (unique pointers are zero cost abstractions).
The join in the for loop is probably not what you want, it will wait for the previously spawned thread and spawn another one after it is finished. If you want parallelism you need another for loop for the joins, but the preferred way would be to use std::for_each(begin(pool), end(pool), [](auto& thread) { thread.join(); }) or something similar.
Use the C++ Core Guidelines and a recent C++ standard (C++17 is the current), C++11 is old and you probably want to learn the modern stuff instead of learning how to write legacy code. http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
C++ is not java, use the stack as much as possible - this is one of the biggest advantages to using C++. Make sure you understand how the stack, constructors and destructors work by heart.
The first question is subjective so someone else would want to give an advice, but I don't see anything awful.
Nothing in C++ standard library is thread-safe except for some rare cases. A good answer on using ofstream in a multithreaded environment is given here.
Not closing a file is indeed an issue. You have to get familiar with RAII as it is one of the first things to learn. The answer by Detonar is a good piece of advice.

Limit function execution time

Is there any way to make a function execute it's code for a specific time, then pause it's execution and move on to another function. I want to be able to make a program that can multitask. I have already tried using <thread>, but whenever I try to run the program it runs one of the threads partially and then the debugger throws a "signal SIGABRT" and stops. Is there any other way of doing this?
Edit:
Here is the code I tried using the threads with. I made this as a test in order to try to get the two functions going at the same time, then add the timer to pause the execution. I want it to be able to run one thread for a short time, then move onto another thread, and to keep on doing this.
#include <iostream>
#include <thread>
using namespace std;
void task1()
{
for (int i=0; i<100; i++)
{
cout << i << '\n';
}
}
void task2()
{
for (int i=0; i<100; i++)
{
cout << i << '\n';
}
}
int main()
{
thread t1(task1);
thread t2(task2);
return 0;
}
The most commonly used way of doing this without multi-threading is to abuse the message loop in used by most GUI frameworks. A bit of work is done in a for loop and then PumpMessages or whatever is called to keep to GUI responsive by processing queued messages and then some more work is done.
In my opinion this is a bad practice. What it actually results in is inconsistent, slow and unresponsive applications.
The other option would be resumable functions such as those available in C# and proposed for C++17. However these are not going to be readily available at the moment.
Getting multi-threading right is hard, as you have already discovered crashes and synchronisation bugs are common and can only be found at run time. However multi-core CPUs are the standard everywhere now and you can't really avoid multi-threading so it is best to learn how to get it right.

Run threads in parallel in C++ [duplicate]

This question already has answers here:
std::thread - "terminate called without an active exception", don't want to 'join' it
(3 answers)
Closed 9 years ago.
I am trying to do a dekker algorithm implementation for homework, I understand the concept but I'm not being able to execute two threads in parallel using C++0x.
#include <thread>
#include <iostream>
using namespace std;
class Homework2 {
public:
void run() {
try {
thread c1(&Homework2::output_one, this);
thread c2(&Homework2::output_two, this);
} catch(int e) {
cout << e << endl;
}
}
void output_one() {
//cout << "output one" << endl;
}
void output_two() {
//cout << "output two" << endl;
}
};
int main() {
try {
Homework2 p2;
p2.run();
} catch(int e) {
cout << e << endl;
}
return 0;
}
My problem is that the threads will return this error:
terminate called without an active exception
Aborted
The only way to success until now for me has been adding c1.join(); c2.join(); or .detach();
the problem is that join(); will wait for the threads to finish, and detach(); ... well Im not sure what detach does because there is no error but also no output, I guess it leaves the threads on their own...
So all this to say:
Does anybody knows how can I do this both threads to run parallel and not sequencial??
The help is must appreciated!
Thanks.-
P.S:
here is what I do for build:
g++ -o output/Practica2.out main.cpp -pthread -std=c++11
The only way to success until now for me has been adding c1.join(); c2.join(); or .detach();...
After you have spawned the 2 threads, your main thread continues on and, based on your code, ends 'pretty' quick (p2.run() then return 0; are relatively close in CPU instruction 'time'). Depending on how quickly the threads started, they might not have had enough CPU time to fully 'spawn' before the program terminated or if they did fully spawn, there might not have been enough time to do the proper cleanup by the kernel. This is also known as a race condition.
Calling join on the spawned threads from the thread you spawned them from allows the threads to finish and clean up properly (under the hood) before your program exits (a good thing). Calling detach works in this scenario too as it releases all resources (under the hood) from your thread object, but keeps the thread active. In the case of calling detach there were no errors reported because the thread objects were detached from the executing threads, so when your program exited, the kernel (nicely) cleaned up the threads for you (or at least that's what might happen, depends on OS/compiler implementation, etc.) so you didn't see your threads ending 'uncleanly'.
So all this to say: Does anybody knows how can I do this both threads to run parallel and not sequencial??
I think you might have some confusion on how threads work. Your threads already run in 'parallel' (so to speak), that is the nature of a thread. Your code posted does not have anything that would be 'parallel' in nature (i.e. parallel computing of data) but your threads are running concurrently (at the same time, or 'parallel' to each).
If you want your main thread to continue without putting the join in the run function, that would require a little more code than what you currently have and I don't want to assume how your code's future should look, but you could take a look at these two questions regarding the std::thread as a member of a class (and executing within such).
I hope that can help.
Ok this is bit more complex but I will try to explain some things in your code.
When you create the threads in the method called run, you want to print two things (imagine you uncomment the lines), but the thread object is destroyed in the stack unwiding of the method which created them (run).
You actually need to do two things, first create the threads and keep them running(for example do it as pointers) and second call the method join to release all the memory and stuff they needed when they are finished.
You can store you threads in a vector something like std::vector<std::thread*>