I would like to check Mysql connections are alive.
(using Mysql-connector-c++)
so.. I call "check function" every 5 minutes
like this
void checkConnection()
{
std::this_thread::sleep_for(std::chrono::minutes(5));
// -- check connection
std::async(std::launch::async, checkConnection); // Here
}
Is it safe..??
In the case you specified, it is safe, because std::launch::async—when by itself—specifies that you want this to be done on a separate thread. The danger, otherwise, would have been stack overflow due to recursive calls.
However, note that the behavior here would be:
Sleep 5 mins on thread T1
Check connection on T1
Start new thread T2
End thread T1
Sleep 5 mins on thread T2
...
So you'd always be using one thread, except you'll pay for creation and destruction each time. It's better to use just one thread, e.g.
void checkConnection(std::atomic<bool>& stopFlag)
{
using namespace std::chrono; // for 5min shorthand, if C++14
while (!stopFlag) {
std::this_thread::sleep_for(5min);
// -- check connection
}
}
Or better yet, use a thread pool for which you can specify delays. But that's not provided by the standard library as of yet.
Related
I have a method that may be used in multiple goroutines and run concurrently.
Inside this method, I have a conditional statement. If the conditional statement is true, I want all other goroutines calling this method to wait for one and only one of the goroutines to execute this conditional statement before proceeding to the next section.
For example:
type SomeClass struct {
mu sync.Mutex
}
func (c *SomeClass) SomeFunc() {
//Do some calculation
if condition {
//This part should be executed by only one goroutine if the condition is true.
//All others must wait for this to finish
}
//Additional calculations
}
And I want to use it like this:
func main(){
//initilize
go someClass.SomeFunc()
//If the condition is true, the following will wait at the conditional statement until the first one finishes the code inside the conditional block
//Once it's done, they can run concurrently
go someClass.SomeFunc()
go someClass.SomeFunc()
}
Edit
This is perhaps not the right design for this so I'm looking for any suggestions on how to implement this.
Edit2:
Note that each routine will have its own condition. This value of condition is not shared between threads. However, the work inside the condition should run only once only if the condition in 2 or more routines happens to be true at the same time.
You'll want a mutex protecting the condition from concurrent read/writes, and then a method for resetting the condition when you wish to execute the synchronous code again.
type SomeClass struct {
conditionMu sync.Mutex
condition bool
}
func (c *SomeClass) SomeFunc() {
// Lock the mutex, so that concurrent calls to SomeFunc will wait here.
c.conditionMu.Lock()
if c.condition {
// Synchronous code goes here.
// Reset the condition to false so that any waiting goroutines won't run the code inside this block again.
c.condition = false
}
// Unlock the mutex, and any waiting goroutines.
c.conditionMu.Unlock()
}
// ResetCondition sets the stored condition to true in a thread-safe manner.
func (c *SomeClass) ResetCondition() {
c.conditionMu.Lock()
c.condition = true
c.conditionMu.Unlock()
}
The other answers to this question were incorrect because they do not satisfy the requirements of the question.
If the lock is added outside the conditional statement, then it will act as a barrier and will force all routines to synchronize at that spot. This is not the point of this question. Suppose resolving the condition value takes a long time, we do not want to check the value one routine at a time. We want to let every process check the condition at once so if the condition is false, we can move forward without stopping.
We want to ensure that the goroutines run in parallel if the condition is not true. Adding a lock inside the method and outside the conditional statement will not allow that to happen.
The following solutions are correct and passed all tests and performed well.
Solution 1:
Use 2 nested conditional statement such as this:
Note that in this case, if the condition is false, no lock will be called and no synchronization is needed. Everything can run in parallel.
type SomeClass struct {
conditionMu sync.Mutex
rwMu sync.RWMutex
additionalWorkRequired bool
}
func (c *SomeClass) SomeFunc() {
//Do some work ...
//Note: The condition is not shared, some routines can have false and some true at the same time, which is fine.
condition := true;
// All routines can check this condition and go inside the block if the condition is true
if condition {
c.rwMutex.Lock()
c.additionalWorkRequired = true
c.rwMutex.Unlock()
//Lock so other routines can wait here for the first one
c.conditionMu.Lock()
if c.additionalWorkRequired {
// Synchronous code goes here.
c.additionalWorkRequired = false
}
//Unlock so all other processors can move forward in parallel
c.conditionMu.unlock()
}
//Finish up the remaining work
}
Solution 2:
Use the do function from sync/singleflight which can handle this situation automatically.
From documentation:
Do executes and returns the results of the given function, making sure that only one execution is in-flight for a given key at a time. If a duplicate comes in, the duplicate caller waits for the original to complete and receives the same results. The return value shared indicates whether v was given to multiple callers.
Edit:
Since many seem to be confused by this question and answer, I'm adding a use case which might make things more clear:
1. Send a HTTP Request
2. If the server returns an error saying credentials are incorrect (This is condition):
2.1. Save current credentials in a local variable
2.2. Acquire the mutex lock
2.2.1. Compare the shared credentials with the ones in the local variable(This is the second condition)
If they are the same, then replace them with new ones
2.3. Unlock
2.4. Retry request
I am working on refactoring some legacy code that suffers from deadlocks. There are two main root causes:
1) the same thread locking the same mutex multiple times, which should not difficult to resolve, and
2) the code occasionally calls into user defined functions which can enter the same code at the top level. I need to lock the mutex before calling user defined functions, but I might end up executing the same code again which will result in a deadlock situation. So, I need some mechanism to tell me that the mutex has already been locked and I should not lock it again. Any suggestions?
Here is a (very) brief summary of what the code does:
class TreeNode {
public:
// Assign a new value to this tree node
void set(const boost::any& value, boost::function<void, const TreeNode&> validator) {
boost::upgrade_lock<boost::shared_mutex> lock(mutexToTree_);
// call validator here
boost::upgrade_to_unique_lock<boost::shared_mutex> ulock(lock);
// set this TreeNode to value
}
// Retrieve the value of this tree node
boost::any get() {
boost::shared_lock<boost::shared_mutex> lock(mutexToTree_);
// get value for this tree node
}
private:
static boost::shared_mutex mutexToRoot_;
};
The problem is that the validator function can call into get(), which locks mutexToRoot_ on the same thread. I could modify mutexToRoot_ to be a recursive mutex but that would prevent other threads from reading the tree during get() operation, which is unwanted behavior.
Since C++11 you can use std::recursive_mutex, which allows the owning thread to call lock or try_lock without blocking/reporting failure, whereas the other threads will block on lock/receive false on try_lock until the owning thread calls unlock as many times as it called lock/try_lock before.
I have the following scenario: (pesudo-code)
CallerObject.method() {
SessionBean1.method1(); // through remote bean interface
// [1]
}
#TransactionAttribute(REQUIRED)
SessionBean1.method1() {
// do something...
Event<myClass>.fire();
// do something...
}
ObserverObject.method2(#Observes(during=AFTER_SUCCESS) myClass) {
sessionBean2.method2(); // through local bean interface
}
#Asynchronous
#TransactionAttribute(REQUIRED)
SessionBean2.method2() {
// do something...
}
==> the following happens:
[1] is only reached AFTER the transaction in SessionBean2.method2() finishes! (Although the last statement in SessionBean1.method1() is reached way before that.)
It's as if SessionBean1.method1()'s transaction somehow isn't "released" (for want of a better word -- it does get committed immediately, before the event handler ObserverObject.method2() is called!) until the asynchronously called Session2.method2()'s transaction finishes as well.
Does anyone know how I could avoid that?
(The point of the whole setup would be to have the long-running SessionBean2.method2() run in the background after T1's completion and have SessionBean1.method1() return as soon as possible.)
P.S.: I have verified that
a) T1 is committed immediately (the records go in the DB)
b) SessionBean2.method2() is called asynchronously (control jumps to the next statement in the calling code immediately)
c) the SessionBean1.method1() doesn't return control to the caller code until T2 finishes
I want a piece of code to be critical for the current team of threads and not global critical.
How can i achieve this ??
quick-sort(args)
{
spawn threads #x
{
critical-region
{
// code
}
}
quick-sort(args)
quick-sort(args)
}
Here the open-mp critical-region construct will block all threads before accessing the critical region. But i don't have problem with two threads entering the critical region as long as they are not spawned at the same time. I want a solution for openMP.
You cannot do that with #pragma omp critical, but you may use OpenMP locks:
quick-sort(args)
{
declare an instance of OpenMP lock
omp_init_lock( the lock instance )
spawn threads #x
{
// critical-region
omp_set_lock( the lock instance )
{
// code
}
omp_unset_lock( the lock instance )
}
omp_destroy_lock( the lock instance )
quick-sort(args)
quick-sort(args)
}
Since each invocation of quick-sort will declare its own lock object, it will give you what you want.
However, from your pseudo-code it seems that you will never have two different thread teams running at the same time, unless there are OpenMP parallel regions in other functions. If the only code that has a parallel region ("spawns threads") is in quick-sort, you would need to have a recursive call to that function from inside the parallel region, which you do not.
I am using boost::signals2 under Red Hat Enterprise Linux 5.3.
My signal creates an object copy and sends it's pointer to subscribers. This was implemented for thread safety to prevent the worker thread from updating a string property on the object at the same time it is being read ( perhaps I should revisit the use of locks? ).
Anyway, my concern is with multiple subscribers that dereference the pointer to the copied object on their own thread. How can I control object lifetime? How can I know all subscribers are done with the object and it is safe to delete the object?
typedef boost::signals2::signal< void ( Parameter* ) > signalParameterChanged_t;
signalParameterChanged_t m_signalParameterChanged;
// Worker Thread - Raises the signal
void Parameter::raiseParameterChangedSignal()
{
Parameter* pParameterDeepCopied = new Parameter(*this);
m_signalParameterChanged(pParameterDeepCopied);
}
// Read-Only Subscriber Thread(s) - GUI (and Event Logging thread ) handles signal
void ClientGui::onDeviceParameterChangedHandler( Parameter* pParameter)
{
cout << pParameter->toString() << endl;
delete pParameter; // **** This only works for a single subscriber !!!
}
Thanks in advance for any tips or direction,
-Ed
If you really have to pass Parameter by pointer to your subscribers, then you should use boost::shared_ptr:
typedef boost::shared_ptr<Parameter> SharedParameterPtr;
typedef boost::signals2::signal< void ( SharedParameterPtr ) > signalParameterChanged_t;
signalParameterChanged_t m_signalParameterChanged;
// The signal source
void Parameter::raiseParameterChangedSignal()
{
SharedParameterPtr pParameterDeepCopied = new Parameter(*this);
m_signalParameterChanged(pParameterDeepCopied);
}
// The subscriber's handler
void ClientGui::onDeviceParameterChangedHandler( SharedParameterPtr pParameter)
{
cout << pParameter->toString() << endl;
}
The shared parameter object sent to your subscribers will be automatically deleted when its reference count becomes zero (i.e. it goes out of scope in all the handlers).
Is Parameter really so heavyweight that you need to send it to your subscribers via pointer?
EDIT:
Please note that using shared_ptr takes care of lifetime management, but will not relieve you of the responsibility to make concurrent reads/writes to/from the shared parameter object thread-safe. You may well want to pass-by-copy to your subscribers for thread-safety reasons alone. In your question, it's not clear enough to me what goes on thread-wise, so I can't give you more specific recommendations.
Is the thread calling raiseParameterChangedSignal() the same as your GUI thread? Some GUI toolkits don't allow concurrent use of their API by multiple threads.