problem mutex-thread "Unlocking mutex owned by another thread ???"

Discussion in 'C++' started by NaeiKinDus, Apr 14, 2007.

  1. NaeiKinDus

    NaeiKinDus Guest

    Hello, i'm trying to program a thread that would be locked (by a
    mutex) and that would only be unlocked once that a function
    (generating data) is done. The purpose is to generate data, and unlock
    the mutex in order to activate the thread once the data is generated.
    I have to do it this way, i can only call the thread if the data are
    generated.

    ********************************************************
    step 1: initialize the mutex

    mx (the mutex is part of the class "cl")

    class Client
    {
    ...

    public:
    pthread_mutex_t mx;

    ...
    }

    pthread_mutex_init(&cl->mx, NULL);
    ********************************************************

    ********************************************************
    step 2:

    as i'm calling a thread, i have to pass in param a structure with the
    mutex :

    struct S_PARAMS
    {
    ...

    pthread_mutex_t *mx;

    ...
    } typedef T_PARAMS;

    i create the thread and i copy the mutex in the param structure :

    pthread_t thread;
    params->mx = &cl->mx;

    if ((thId = pthread_create(&thread, NULL, OBody::thFileSender, (void
    *)params)) != 0)
    {
    THREAD NOT CREATED ... throw ...
    }
    else
    {
    I SET SOME FLAG TO KNOW MY THREAD HAS BEEN CREATED
    }
    ********************************************************

    ********************************************************
    step 3:

    i lock my thread :

    void *OBody::thFileSender(void *lpParam)
    {
    cout << "locking MUTX*****" << endl;
    cout << pthread_mutex_lock(params->mx) << endl;
    cout << "unlocked MUTX *****" << endl;

    ... (sending data)
    }

    ********************************************************

    ********************************************************
    step 4:

    once i know my functions generating data are done, i call the thread
    unlocking function.


    cout << "*** before unlock ***" << endl;
    pthread_mutex_unlock(&cl.mx);
    cout << "*** after unlock ***" << endl;

    ********************************************************


    Finally i get :

    ********************************************************

    ....

    locking MUTX*****
    0
    unlocked MUTX *****

    .... (generated data)


    *** before unlock ***
    server: Error detected by libpthread: Unlocking mutex owned by another
    thread.
    Detected by file "/root/netbsd-3.0/src/lib/libpthread/
    pthread_mutex.c", line 347, function "pthread_mutex_unlock".
    See pthread(3) for information.

    ....

    ********************************************************


    What i understand is that the mutex is not locking the thread because
    in the step3,
    the "cout << "locking MUTX*****" << endl;" is done when is start the
    program.

    I put a sleep(10) in order to be sure that the thread was still
    running without calling thread_unlock.

    Moreover, when i try to unlock the thread, i get the error "Unlocking
    mutex owned by another thread.".

    all the mutex functions (init, lock, unlock) return 0 which mean that
    the function are running correctly.

    i have been working on this problem for hours and hours, i'm not a
    specialist of the mutex/thread.

    Thank you for your help.
    NaeiKinDus, Apr 14, 2007
    #1
    1. Advertising

  2. NaeiKinDus

    James Kanze Guest

    On Apr 14, 7:11 pm, "NaeiKinDus" <> wrote:
    > Hello, i'm trying to program a thread that would be locked (by a
    > mutex) and that would only be unlocked once that a function
    > (generating data) is done. The purpose is to generate data, and unlock
    > the mutex in order to activate the thread once the data is generated.
    > I have to do it this way, i can only call the thread if the data are
    > generated.


    I'm not sure I understand that paragraph. However, there are
    one or two things that look more than dubious...

    > if ((thId = pthread_create(&thread, NULL, OBody::thFileSender, (void
    > *)params)) != 0)


    What are you passing as third pointer? It has to be a global
    function, with `extern "C"' linkage. If OBody is a namespace,
    this could be OK, but the rest of the code makes me think that
    OBody is member function of a class, and there is no way that a
    member function of a class can be passed as an argument to a
    function, period, and there's also no way that it can have "C"
    linkage.

    > i lock my thread :


    > void *OBody::thFileSender(void *lpParam)
    > {
    > cout << "locking MUTX*****" << endl;
    > cout << pthread_mutex_lock(params->mx) << endl;
    > cout << "unlocked MUTX *****" << endl;


    > ... (sending data)


    > }


    Where do you unlock it? (Your output says "unlocked MUTX", but
    it looks to me like you just locked it.) After this operation,
    the thread which has executed the pthread_mutex_lock owns the
    mutex. No one else can unlock it, for rather obvious reasons.

    In C++, the usual way of handling this is to use a RAII class;
    that way, the mutex will be unlocked even if there is an
    exception.

    [...]
    > What i understand is that the mutex is not locking the thread because
    > in the step3,


    I'm not sure what you mean by "the mutex locking the thread". A
    thread acquires a mutex. Once a thread has acquired a mutex,
    then any other thread which attempts to acquire it will block
    until the thread holding the mutex releases
    (pthread_mutex_unlock) it.

    [...]
    > Moreover, when i try to unlock the thread, i get the error
    > "Unlocking mutex owned by another thread.".


    So you know exactly what your error is.

    > all the mutex functions (init, lock, unlock) return 0 which mean that
    > the function are running correctly.


    > i have been working on this problem for hours and hours, i'm not a
    > specialist of the mutex/thread.


    You might want to check out the Butenhof. It's the standard
    reference for Posix threading. (I also recommend it for people
    doing Windows programming, as it has enough general information
    to be of use to them as well.)

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 15, 2007
    #2
    1. Advertising

  3. NaeiKinDus

    NaeiKinDus Guest

    On 15 avr, 01:43, "James Kanze" <> wrote:
    > On Apr 14, 7:11 pm, "NaeiKinDus" <> wrote:
    >
    > > Hello, i'm trying to program a thread that would be locked (by a
    > > mutex) and that would only be unlocked once that a function
    > > (generating data) is done. The purpose is to generate data, and unlock
    > > the mutex in order to activate the thread once the data is generated.
    > > I have to do it this way, i can only call the thread if the data are
    > > generated.

    >
    > I'm not sure I understand that paragraph. However, there are
    > one or two things that look more than dubious...


    Rephrased: I had to block a thread until the calling process says it
    can do what it's meant to do.

    >
    > > if ((thId = pthread_create(&thread, NULL, OBody::thFileSender, (void
    > > *)params)) != 0)

    >
    > What are you passing as third pointer? It has to be a global
    > function, with `extern "C"' linkage. If OBody is a namespace,
    > this could be OK, but the rest of the code makes me think that
    > OBody is member function of a class, and there is no way that a
    > member function of a class can be passed as an argument to a
    > function, period, and there's also no way that it can have "C"
    > linkage.
    >


    Nevermind. Just a noob thing a mate did (we're working in group ) -_-'
    By the way, why does the function actually works ? It was successfully
    called !
    Anyway... Fixed.

    > > i lock my thread :
    > > void *OBody::thFileSender(void *lpParam)
    > > {
    > > cout << "locking MUTX*****" << endl;
    > > cout << pthread_mutex_lock(params->mx) << endl;
    > > cout << "unlocked MUTX *****" << endl;
    > > ... (sending data)
    > > }

    >
    > Where do you unlock it? (Your output says "unlocked MUTX", but
    > it looks to me like you just locked it.) After this operation,
    > the thread which has executed the pthread_mutex_lock owns the
    > mutex. No one else can unlock it, for rather obvious reasons.
    >


    The "Unlocked" cout was supposed to appear when the thread would have
    been released...


    > > What i understand is that the mutex is not locking the thread because
    > > in the step3,

    >
    > I'm not sure what you mean by "the mutex locking the thread". A
    > thread acquires a mutex. Once a thread has acquired a mutex,
    > then any other thread which attempts to acquire it will block
    > until the thread holding the mutex releases
    > (pthread_mutex_unlock) it.
    >
    > [...]


    Got it :) Thanks, we'll work on it !

    >
    > > Moreover, when i try to unlock the thread, i get the error
    > > "Unlocking mutex owned by another thread.".

    >
    > So you know exactly what your error is.
    >
    > > all the mutex functions (init, lock, unlock) return 0 which mean that
    > > the function are running correctly.
    > > i have been working on this problem for hours and hours, i'm not a
    > > specialist of the mutex/thread.

    >
    > You might want to check out the Butenhof. It's the standard
    > reference for Posix threading. (I also recommend it for people
    > doing Windows programming, as it has enough general information
    > to be of use to them as well.)
    >


    Again, thanks for your help !

    > --
    > James Kanze (Gabi Software) email:
    > Conseils en informatique orientée objet/
    > Beratung in objektorientierter Datenverarbeitung
    > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    NaeiKinDus, Apr 15, 2007
    #3
  4. NaeiKinDus

    James Kanze Guest

    On Apr 15, 11:28 am, "NaeiKinDus" <> wrote:
    > On 15 avr, 01:43, "James Kanze" <> wrote:


    > > On Apr 14, 7:11 pm, "NaeiKinDus" <> wrote:

    >
    > > > Hello, i'm trying to program a thread that would be locked (by a
    > > > mutex) and that would only be unlocked once that a function
    > > > (generating data) is done. The purpose is to generate data, and unlock
    > > > the mutex in order to activate the thread once the data is generated.
    > > > I have to do it this way, i can only call the thread if the data are
    > > > generated.


    > > I'm not sure I understand that paragraph. However, there are
    > > one or two things that look more than dubious...


    > Rephrased: I had to block a thread until the calling process says it
    > can do what it's meant to do.


    You mean you start a thread, just so that it can wait until you
    decide it can work. In that case, you need for the calling
    thread to lock the mutex before starting the thread, then unlock
    it when its OK. The called thread tries acquire the mutex,
    blocking until the calling thread releases it. Just don't
    forget to have the called thread release the mutex too, when it
    is through.

    Still, I would definitly consider just putting off starting the
    thread until it can do what it's meant to do.

    > > > if ((thId = pthread_create(&thread, NULL, OBody::thFileSender, (void
    > > > *)params)) != 0)


    > > What are you passing as third pointer? It has to be a global
    > > function, with `extern "C"' linkage. If OBody is a namespace,
    > > this could be OK, but the rest of the code makes me think that
    > > OBody is member function of a class, and there is no way that a
    > > member function of a class can be passed as an argument to a
    > > function, period, and there's also no way that it can have "C"
    > > linkage.


    > Nevermind. Just a noob thing a mate did (we're working in group ) -_-'
    > By the way, why does the function actually works ? It was successfully
    > called !


    I don't know. As I said, to begin with, supposing that
    thFileSender is a member function, the code shouldn't even
    compile; you can't pass a member function as a parameter,
    period, and there's no implicit conversion of member function to
    pointer. (I think VC++ did implicitly convert a member function
    to a pointer without a &.)

    The second thing is that the type of the function is wrong. If
    the function is not static, of course, the type is way, way
    wrong, and I can't imagine it ever working (but again, I've
    heard about some wierd behavior in VC++). But even if the
    member function is static, it still won't be `extern "C"'. Now,
    Posix doesn't define a C++ binding, and C++ doesn't say anything
    about pthread_create, so it's up to the implementation. But in
    all the implementations I know (Solaris and Linux),
    pthread_create is NOT overloaded, and requires a function with
    "C" linkage. The compiler should complain. (Sun CC does,
    although it is only a warning, and not an error. G++ doesn't;
    this is a bug in g++.)

    > Anyway... Fixed.


    > > > i lock my thread :
    > > > void *OBody::thFileSender(void *lpParam)
    > > > {
    > > > cout << "locking MUTX*****" << endl;
    > > > cout << pthread_mutex_lock(params->mx) << endl;
    > > > cout << "unlocked MUTX *****" << endl;
    > > > ... (sending data)
    > > > }


    > > Where do you unlock it? (Your output says "unlocked MUTX", but
    > > it looks to me like you just locked it.) After this operation,
    > > the thread which has executed the pthread_mutex_lock owns the
    > > mutex. No one else can unlock it, for rather obvious reasons.


    > The "Unlocked" cout was supposed to appear when the thread would have
    > been released...


    Before going any further, you're going to have to read a general
    book about threading, at least enough to know the basic
    vocabulary. What do you mean by "released"? A thread is
    started, it runs, and it exits (terminates). If it hasn't been
    detached, someone, somewhere, must join with it. But it's never
    "released".

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 15, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    1,483
  2. NaeiKinDus
    Replies:
    1
    Views:
    559
    Jack Klein
    Apr 14, 2007
  3. Roy Smith

    Mutex not thread safe? PEP-3108.

    Roy Smith, Sep 23, 2008, in forum: Python
    Replies:
    1
    Views:
    282
  4. sven
    Replies:
    2
    Views:
    1,916
    Roy Smith
    Dec 4, 2009
  5. Guest
    Replies:
    10
    Views:
    237
    Robert Klemme
    Dec 27, 2005
Loading...

Share This Page