In a C++ class, How can I limit the number calls/uses of a certain function for each thread?
For example, each thread is allowed only to use a certain data setter for 3 times.
You just have to count how often the method has been called for each thread and then react accordingly:
void Foo::set(int x) {
static std::map<std::thread::id,unsigned> counter;
auto counts = ++counter[std::this_thread::get_id()];
if (counts > max_counts) return;
x_member = x;
}
This is just to outline the basic idea. I am not so sure about the static map. I am not even sure if it is a good idea to let the method itself implement the counter. I would rather put this elsewhere, eg each thread could get a CountedFoo instance that holds a reference to the actual Foo object and the CountedFoo controls the maximum number of calls.
PS: And of course, don't forget to use some synchronisation when multiple threads are calling the method concurrently (for the sake of brevity I did not include any mutex or similar in the above code).
Using std::map to store thread Ids as sugested by #formerlyknownas_463035818 would probably be the most robust solution, but synchronization might prove more complex.
The fastest solution to this issue is using thread_local. This will enable each thread to have its own copy of the counter. Here is the working example which might prove useful.
thread_local unsigned int N_Calls = 0;
std::mutex mtx;
void controlledIncreese(const std::string& thread_name){
while (N_Calls < 3) {
++N_Calls;
std::this_thread::sleep_for(std::chrono::seconds(rand() % 2));
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Call for thread " << thread_name.c_str() << ": " << N_Calls << '\n';
}
}
int main(){
std::thread first_t(controlledIncreese, "first"), second_t(controlledIncreese, "second");
first_t.join();
second_t.join();
}
Since both Threads are using std::cout the actual output will be sequential, so this specific example is not very useful but it does provide easy working solution to thread execution counting problem.
Related
When I run several std::threads in parallell and need to cancel other threads in a deferred manner if one thread fails I use a std::atomic<bool> flag:
#include <thread>
#include <chrono>
#include <iostream>
void threadFunction(unsigned int id, std::atomic<bool>& terminated) {
srand(id);
while (!terminated) {
int r = rand() % 100;
if (r == 0) {
std::cerr << "Thread " << id << ": an error occured.\n";
terminated = true; // without this line we have to wait for other thread to finish
return;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main()
{
std::atomic<bool> terminated = false;
std::thread t1(&threadFunction, 1, std::ref(terminated));
std::thread t2(&threadFunction, 2, std::ref(terminated));
t1.join();
t2.join();
std::cerr << "Both threads finished.\n";
int k;
std::cin >> k;
}
However now I am reading about std::stop_sourceand std::stop_token.
I find that I can achieve the same as above by passing both a std::stop_sourceby reference and std::stop_token by value to the thread function?
How would that be superior?
I understand that when using std::jthread the std::stop_token is very convenient if I want to stop threads from outside the threads.
I could then call std::jthread::request_stop() from the main program.
However in the case where I want to stop threads from a thread is it still better?
I managed to achieve the same thing as in my code using std::stop_source:
void threadFunction(std::stop_token stoken, unsigned int id, std::stop_source source) {
srand(id);
while (!stoken.stop_requested()) {
int r = rand() % 100;
if (r == 0) {
std::cerr << "Thread " << id << ": an error occured.\n";
source.request_stop(); // without this line we have to wait for other thread to finish
return;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main()
{
std::stop_source source;
std::stop_token stoken = source.get_token();
std::thread t1(&threadFunction, stoken, 1, source);
std::thread t2(&threadFunction, stoken, 2, source);
t1.join();
t2.join();
std::cerr << "Both threads finished.\n";
int k;
std::cin >> k;
}
Using std::jthread would have resulted in more compact code:
std::jthread t1(&threadFunction, 1, source);
std::jthread t2(&threadFunction, 2, source);
But that did not seem to work.
It didn't work because std::jthread has a special feature where, if the first parameter of a thread-function is a std::stop_token, it fills that token in by an internal stop_source object.
What you ought to do is only pass a stop_source (by value, not by reference), and extract the token from it within your thread function.
As for why this is better than a reference to an atomic, there are a myriad of reasons. The first being that stop_source is a lot safer than a bare reference to an object whose lifetime is not under the local control of the thread function. The second being that you don't have to do std::ref gymnastics to pass parameters. This can be a source of bugs since you might accidentally forget to do that in some place.
The standard stop_token mechanism has features beyond just requesting and responding to a stop. Since the response to a stop happens at an arbitrary time after issuing it, it may be necessary to execute some code when the stop is actually requested rather than when it is responded to. The stop_callback mechanism allows you to register a callback with a stop_token. This callback will be called in the thread of the stop_source::request_stop call (unless you register the callback after the stop was requested, in which case it's called right when you register it). This can be useful in limited cases, and it's not simple code to write yourself. Especially when all you have is an atomic<bool>.
And then there's simple readability. Passing a stop_source tells you exactly what is going on without having to even see the name of a parameter. Passing an atomic<bool> tells you very little from just the typename; you have to look at the parameter name or its usage in the function to know that it is for halting the thread.
Apart from being more expressive and communicating intentions better, stop_token and friends achieve something really important for jthread. To understand it you have to consider its destructor which looks something like this:
~jthread()
{
if(joinable())
{
// Not only user code, but the destructor as well
// will let your callback know it's time to go.
request_stop();
join();
}
}
by encapsulating a stop_source, jthread facilitates what is called cooperative cancellation. As you've also noted, you never have to pass the stop_token to a jthread, just provide a callback that accepts the token as its first parameter. What happens next is that the class can detect that your callback accepts a stop token and pass a token to its internal stop source when calling it.
What does this mean for cooperative cancellation? Safer termination of course! Since jthread will always attempt to join on destruction, it now has the means to prevent endless loops and deadlocks where two or more threads wait for each other to finish. By using stop_token your code can make sure that it can safely join when it's time to go.
However in the case where I want to stop threads from a thread is it still better?
Now regarding the feature you are requesting, that's what C# calls "linked cancellation". Yes, there are requests and discussions to add a parameter in the jthread constructor so that it can refer to an external stop source, but that's not yet available (and has many implications). Doing something similar purely with stop tokens would require a stop_callback to tie all cancellations together, but still it could be suboptimal (as shown in the link). The bottom line is that jthread needs stop_token, but in some cases you may not need jthread, especially if the following solution does not appeal to you:
stop_source ssource;
std::stop_callback cb {ssource.get_token(), [&] {
t1.request_stop();
t2.request_stop();
}};
ssource.request_stop(); // This stops boths threads.
The good news is that if you don't fall into the suboptimal pattern described in the link (i.e. you don't need an asynchronous termination), then this functionality is easy to abstract into a utility, something like:
auto linked_cancellations = [](auto&... jthreads) {
stop_source s;
return std::make_pair(s, std::stop_callback{
s.get_token(), [&]{ (jthreads.request_stop(), ...); }});
};
which you'd use as
auto [stop_source, cb] = linked_cancellations(t1, t2);
// or as many thread objects as you want to link ^^^
stop_source.request_stop(); // Stops all the threads that you linked.
Now if you want to control the linked threads from within the thread, I'd use the initial pattern (std::atomic<bool>), since having a callback with both a stop token and a stop source is somewhat confusing.
Update 9th June 2020:
Consolidating all the comments and answers here, and putting some more thought to this, I have created a flowchart below (click to zoom) to help decide when to use std::promise/future, and what are the trade-offs.
Original post is as follows:
I have been thinking about the real benefit of the std::promise/future mechanism. Examples almost everywhere tout this pattern - a single producer, single producer scenario where the producer notifies the consumer one-time that the resource in question is ready for consumption:
#include <iostream>
#include <future>
#include <thread>
using namespace std::chrono_literals;
struct StewableFood {
int tenderness;
};
void slow_cook_for_12_hours(std::promise<StewableFood>& promise_of_stew) {
std::cout << "\nChef: Starting to cook ...";
// Cook till 100% tender
StewableFood food{ 0 };
for (int i = 0; i < 10; ++i) {
std::this_thread::sleep_for(10ms);
food.tenderness = (i + 1) * 10;
std::cout << "\nChef: Stewing ... " << food.tenderness << "%";
}
// Notify person waiting on the promise of stew that the promise has been fulfilled.
promise_of_stew.set_value(food);
std::cout << "\nChef: Stew is ready!";
}
void wait_to_eat_stew(std::future<StewableFood>& potenial_fulfilment_of_stew) {
std::cout << "\nJoe: Waiting for stew ...";
auto food = potenial_fulfilment_of_stew.get();
std::cout << "\nJoe: I have been notified that stew is ready. Tenderness " << food.tenderness << "%! Eat!";
}
int main()
{
std::promise<StewableFood> promise_of_stew;
auto potenial_fulfilment_of_stew = promise_of_stew.get_future();
std::thread async_cook(slow_cook_for_12_hours, std::ref(promise_of_stew));
std::thread async_eat(wait_to_eat_stew, std::ref(potenial_fulfilment_of_stew));
async_cook.join();
async_eat.join();
return 0;
}
To me, all this asynchronicity serves no purpose, because ultimately, the consumer's blocking wait on future::get makes this kind of usage equivalent to a single-threaded one with sequential produce-then-consume. I initially thought my example above is contrived. But if we look at the one-time use only constraint of a std::promise/future pair (i.e. you cannot re-write to the original promise nor re-read from the original future), it then follows that the above example becomes the only viable use case, since:
The set-once constraint means there can be only one producer, and
The get-once constraint means there can be only one consumer, and
Inferred from the above 2 set/get-once constraints, there shall be no looping that causes re-use on the same promise/future.
If the usage pattern in the above example is indeed the only viable use case, it then follows that there is no advantage in using std::promise, compared to doing just:
void cook_stew_then_eat() {
auto stew = slow_cook_for_12_hours();
// wait 12 hours
eat_stew(stew);
}
int main() {
std::thread t(cook_stew_then_eat);
t.join();
return 0;
}
Now, this conclusion seems suspicious. I am quite sure there is a good use case for std::promise which cannot be replaced by a single threaded sequential-produce-then-consume version which doesn't involve std::promise.
Question: What is that use case(s)?
Note: It is tempting to speculate that perhaps std::promise/future somehow allows us to asynchronously do something else without waiting on the fulfilment - might that be the advantage? Definitely not, because we can achieve the identical effect by putting that "something else" (e.g. some important work) in another thread. To illustrate:
// cook and eat threads use std::promise/future
std::thread cook(...);
std::thread eat(...);
// Let's do important work on another thread
std::thread important_work(...);
cook.join();
eat.join();
important_work.join();
is identical to this solution that doesn't use std::promise/future:
// sequentially cook then eat, NO NEED to use std::promise/future
std::thread cook_then_eat(...);
// Let's do important work on another thread
std::thread important_work(...);
cook_then_eat.join();
important_work.join();
No, you are actually correct, future/promise pattern can always be replaced with manual thread management (via thread joins, condition variables and mutexes) if you are careful about synchronization and object lifetimes.
The primary benefit of future/promise pattern is abstraction. It hides lifetime management and synchronization of the shared state from you, freeing you from the burden of doing it yourself.
Once the producer has a promise it doesn't need to know anything else about the consuming side, and likewise for the consumer and future. This makes it possible to write more concise, less error prone, and less coupled code.
Also keep in mind that as of C++20 std::future still lacks continuations, which makes it a lot less powerful than it could be.
What is that use case(s)?
Any work that doesn't depend on the result of the promise can be done on other threads before waiting on the promise.
Let's extend your example to a stew competition
extern void slow_cook_for_12_hours(std::promise<StewableFood>& promise_of_stew);
extern Grade rate_stew(const StewableFood &);
std::map<Chef, Grade> judge_stew_competition(std::map<Chef, std::future<StewableFood>>& entries)
{
std::map<Chef, Grade> results;
for (auto & [chef, fut] : entries) { results[chef] = rate_stew(fut.get()); }
return results;
}
int main()
{
std::map<Chef, std::promise<StewableFood>> promises_of_stew = { ... };
std::map<Chef, std::future<StewableFood>> fulfilment_of_stews;
std::vector<std::thread> async_cook;
for (auto & [chef, promise] : promises_of_stew)
{
fulfilment_of_stews[chef] = promise.get_future();
async_cook.emplace(slow_cook_for_12_hours, std::ref(promise));
}
std::thread async_judge(judge_stew_competition, std::ref(fulfilment_of_stews));
for (auto & thread : async_cook) { thread.join(); }
async_judge.join();
return 0;
}
Examples almost everywhere tout this pattern - a single producer, single producer scenario where the producer notifies the consumer one-time that the resource in question is ready for consumption.
May be that is not a good example.
Another example is a task that requires resources/datasets from different providers and there are only blocking calls available to fetch resources (or non-blocking calls cannot easily be integrated into one event loop in your application). In this case your consumer thread launches all resources requests as std::async and waits till they all complete in parallel, rather than sequentially. In this case it takes max(times) rather than sum(times) to fetch all the datasets, where times is an array of each provider response time.
I have tried to find a similar problem, but was unable to find it, or my knowledge is not enough to recognize the similarity.
I have a main loop creating an object, whereas this object has an infinite loop to process a matrix and do stuff with this matrix. I call this process function within a separate thread an detach it, so it is able to process the matrix multiple times, while the main loop might just wait for something and does nothing.
After a while the main loop receives a new matrix, while I represented it by just creating a new matrix and passes this new matrix into the object. The idea is that, due to waiting a few seconds before processing in the infinite while loop again, the update function can lock the mutex and the mutex is not (almost) frequently locked.
Below I tried to code a minimal Example.
class Test
{
public:
Test();
~Test();
void process(){
while(1){
boost::mutes::scoped_lock locker(mtx);
std::cout << "A" << std::endl;
// do stuff with Matrix
std::cout << "B" << std::endl;
mtx.unlock();
//wait for few microseconds
}
}
void updateMatrix(matrix MatrixNew){
boost::mutes::scoped_lock locker(mtx);
std::cout << "1" << std::endl;
Matrix = MatrixNew;
std::cout << "2" << std::endl;
}
private:
boost::mutex mtx;
matrix Matrix;
}
int main(){
Test test;
boost::thread thread_;
thread_ = boost::thread(&Test::process,boost::ref(test));
thread_.detach();
while(once_in_a_while){
Matrix MatrixNew;
test.updateMatrix(MatrixNew);
}
}
Unfortunately a race condition occurs. Process and Update have multiple steps within the locked mutex environment, while I print stuff to the console between these steps. I found that, both, the matrix is messed up and Letters/Numbers to occur parallel and not consecutive.
Any ideas why this occurs?
Best wishes and thanks in advance
while(1){
boost::mutes::scoped_lock locker(mtx);
std::cout << "A" << std::endl;
// do stuff with Matrix
std::cout << "B" << std::endl;
mtx.unlock();
//wait for few microseconds
}
Here you manually unlock mtx. Then sometime later the scoped_lock (called locker) also unlocks the mutex in its destructor (which is the point of that class). I dont know what the guarantee's boost::mutex requires but unlocking it more times than you locked it can't lead to anything good.
Instead of
mtx.unlock(); you presumably want locker.unlock();
Edit: A recommendation here would be to avoid using boost for this and use standard c++ instead. threading has been part of the standard since C++11 (8 years!) so presumably all your tools will now support it. Using standardised code/tools gives you better documentation and better help as they're much more well known. I'm not knocking boost (a lot of the standard started in boost) but once something has been consumed into the standard you should strongly think about using it.
I've worked a decent amount with threading in C on linux and now I'm trying to do the same but with c++ on Windows, but I'm having trouble with printing to the standard output. In the function the thread carries out I have:
void print_number(void* x){
int num = *(static_cast<int*> (x));
std::cout << "The number is " << num << std::endl;
}
wrapped in a loop that creates three threads. The problem is that although everything gets printed, the threads seem to interrupt each other between each of the "<<"'s.
For example, the last time I ran it I got
The number is The number is 2The number is 3
1
When I was hoping for each on a separate line. I'm guessing that each thread is able to write to the standard output after another has written a single section between "<<"s. In C, this wasn't a problem because the buffer wasn't flushed until everything I needed the write was there, but that's not the case now I don't think. Is this a case of a need for a mutex?
In C++, we first of all would prefer to take arguments as int*. And then, we can just lock. In C++11:
std::mutex mtx; // somewhere, in case you have other print functions
// that you want to control
void print_number(int* num) {
std::unique_lock<std::mutex> lk{mtx}; // RAII. Unlocks when lk goes out of scope
std::cout << "The number is " << *num << std::endl;
}
If not C++11, there's boost::mutex and boost::mutex::scoped_lock that work the same way and do the same thing.
Your C example worked by accident; printf and the like aren't atomic either.
This is indeed a case for a mutex. I typically allocate it static function locally. E.g.:
void atomic_print(/*args*/) {
static MyMutex mutex;
mutex.acquire();
printf(/*with the args*/);
mutex.release();
}
I was reading through a Boost Mutex tutorial on drdobbs.com, and found this piece of code:
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>
boost::mutex io_mutex;
void count(int id)
{
for (int i = 0; i < 10; ++i)
{
boost::mutex::scoped_lock
lock(io_mutex);
std::cout << id << ": " <<
i << std::endl;
}
}
int main(int argc, char* argv[])
{
boost::thread thrd1(
boost::bind(&count, 1));
boost::thread thrd2(
boost::bind(&count, 2));
thrd1.join();
thrd2.join();
return 0;
}
Now I understand the point of a Mutex is to prevent two threads from accessing the same resource at the same time, but I don't see the correlation between io_mutex and std::cout. Does this code just lock everything within the scope until the scope is finished?
Now I understand the point of a Mutex is to prevent two threads from accessing the same resource at the same time, but I don't see the correlation between io_mutex and std::cout.
std::cout is a global object, so you can see that as a shared resource. If you access it concurrently from several threads, those accesses must be synchronized somehow, to avoid data races and undefined behavior.
Perhaps it will be easier for you to notice that concurrent access occurs by considering that:
std::cout << x
Is actually equivalent to:
::operator << (std::cout, x)
Which means you are calling a function that operates on the std::cout object, and you are doing so from different threads at the same time. std::cout must be protected somehow. But that's not the only reason why the scoped_lock is there (keep reading).
Does this code just lock everything within the scope until the scope is finished?
Yes, it locks io_mutex until the lock object itself goes out of scope (being a typical RAII wrapper), which happens at the end of each iteration of your for loop.
Why is it needed? Well, although in C++11 individual insertions into cout are guaranteed to be thread-safe, subsequent, separate insertions may be interleaved when several threads are outputting something.
Keep in mind that each insertion through operator << is a separate function call, as if you were doing:
std::cout << id;
std::cout << ": ";
std::cout << i;
std::cout << endl;
The fact that operator << returns the stream object allows you to chain the above function calls in a single expression (as you have done in your program), but the fact that you are having several separate function calls still holds.
Now looking at the above snippet, it is more evident that the purpose of this scoped lock is to make sure that each message of the form:
<id> ": " <index> <endl>
Gets printed without its parts being interleaved with parts from other messages.
Also, in C++03 (where insertions into cout are not guaranteed to be thread-safe) , the lock will protect the cout object itself from being accessed concurrently.
A mutex has nothing to do with anything else in the program
(except a conditional variable), at least at a higher level.
A mutex has two effeccts: it controls program flow, and prevents
multiple threads from executing the same block of code
simultaneously. It also ensures memory synchronization. The
important issue here, is that mutexes aren't associated with
resources, and don't prevent two threads from accessing the same
resource at the same time. A mutex defines a critical section
of code, which can only be entered by one thread at a time. If
all of the use of a particular resource is done in critical
sections controled by the same mutex, then the resource is
effectively protected by the mutex. But the relationship is
established by the coder, by ensuring that all use does take
place in the critical sections.