Reputation: 60441
In my code, I have a function that operates with static random engine generators and I would like to be able to throw an error if the user tries to call this function from threads different from the main one.
As an example, if you consider the following function :
void f()
{
if (/* SOMETHING */) {
throw std::future_error("ERROR = f() : cannot be executed in parallel");
}
}
what would be /* SOMETHING */
?
Upvotes: 2
Views: 121
Reputation: 7209
A much, much, much better solution would be to make your retrieval of random numbers thread-safe.
This can be done one of two ways:
Lets talk about #1. Since you propose wrapping your calls to get random numbers, it isn't too farfetched to wrap those calls with a mutex. Rather than simply presenting the problem to the user at runtime (which is generally a really poor development choice), we've just solved the problem instead. The only downside is that we've slowed down calls to our random number generator -- which is probably acceptable, but if it isn't...onto option #2.
And, for #2... You say that this is a static random number generator. Perhaps that means that you cannot make another copy of it, but this is worth mentioning anyway. rand
and srand
are like this. But, if you are using something like C++11's std::uniform_int_distribution
, you should have no problem creating a copy for each thread. (Perhaps consider std::thread_local
if you cannot find a good place to put each thread's copy.)
Upvotes: 1
Reputation: 1210
Although I don't think what you're trying to achieve is very elegant (locking or saving your random engine generator's state per thread, e.g. using a thread local storage, might be better), here a solution to what you asked for:
static const auto mainThreadId = std::this_thread::get_id();
void f()
{
if (std::this_thread::get_id() != mainThreadId) {
throw std::future_error("ERROR = f() : cannot be executed in parallel"
"/from a thread other than the main one");
}
}
Upvotes: 2
Reputation: 5213
I am not very experienced in threading, but somewhy I am tempted to do something along the line of singletons/other design patterns.
This being said, I do not believe this idea is very elegant, and I do not know why you are trying to do this, so I do not know how to suggest any alternatives...
Although I do think a singleton can be made in main, so that any attempts to call f from other threads will be prevented.
Singleton is usually misused so... I'd be careful.
Upvotes: 2