|
Threads-Devel : |
Subject: [Threads-devel] a bad way to synchronize?
From: nico (nicolas.guillot_at_[hidden])
Date: 2011-01-23 16:29:46
Hello.
I use a library where function are mainly asynchronous.
The service I provide must make synchronous functions that are asynchronous in
the library.
I use boost::mutex in a strange way: lock in a thread, unlocked in another.
It works for me, but is this behavior undefined and it works by luck? (by
lock ;-) )
Here follows a quick explanation an code snippet to illustrate:
- I lock a mutex in a thread.
- I call the asynchronous function, passing a callback
- I try to lock again the mutex: the thread that has just called the
function is blocked
- The asynchronous function completes, calling the callback in another
thread.
- the mutex is unlocked in this thread and callback
- the calling thread unblocks
- et voila..
#include <iostream>
using namespace std;
#include "boost/thread/thread.hpp"
#include "boost/function/function0.hpp"
#include "boost/bind.hpp"
using namespace boost;
using namespace boost::this_thread;
using namespace boost::posix_time;
struct AsynchronousService
{
void serviceAsync(boost::function0<void> callback)
{
sleep(milliseconds(1000));
callback();
}
};
struct SynchronousCaller
{
SynchronousCaller()
{
}
void call()
{
// lock the mutex
mutex_.lock();
function0<void> cb = bind(&SynchronousCaller::callback, this);
thread(&AsynchronousService::serviceAsync, &service_, cb);
// try to lock again the mutex: it will be acquired when
serviceAsync completes
unique_lock<mutex> lock(mutex_);
}
void callback()
{
mutex_.unlock();
}
AsynchronousService service_;
mutex mutex_;
};
int main()
{
cout << "begin" << endl;
SynchronousCaller caller;
caller.call();
cout << "end" << endl;
return 0;
}
Is this practice bad?
Should I prefer a mechanism based on boost::condition_variable?
I prefered the way I did, because it relies only on a mutex. With a
condition_variable, their would be a little more stuff (a bool for
completion, a mutex to protect it, and the condition_variable
In fact I have 2 particular questions:
1. 2 consecutive locks on the same mutex on the same thread: is it
undefined behavior? It seems yes when boost 1.32, but no today (boost 1.44 -
1.45)
2. Even if it is "again the nature of a mutex", is it bad to lock in a
thread, and unlock in another, if like here, I'm sure there is no concurrent
access t the mutex?
Thank you for your answers.