Boost logo

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.



Threads-Devel list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk