maxsand
maxsand

Reputation: 9

Mutex waits forever after destroy and re-init

I am trying to create a multi-threaded app in C. At some point the program waits when trying to acquire lock on mutexQueue. but i don't know why. This happens after recreation of the mutex.

for(int i = 80; i<= 8080; i++)
{
    pthread_mutex_init(&mutexQueue,NULL);
    ...
    pthread_mutex_lock(&mutexQueue); <= here it waits forever, after the first iteration (when i=81)
    ...
    pthread_mutex_destroy(&mutexQueue);
}

First time it passes after pthread_mutex_lock therefore it can acquire lock, second time not.

Is there a problem to destroy the mutex and then re-init it after?

Full program execution in real time : https://onlinegdb.com/T5kzCaFUA

EDIT: as @John Carter suggested and reading current pthread documentation (https://pubs.opengroup.org/onlinepubs/007904875/functions/pthread_mutex_destroy.html) it writes :

In cases where default mutex attributes are appropriate, the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes that are statically allocated. The effect shall be equivalent to dynamic initialization by a call to pthread_mutex_init() with parameter attr specified as NULL, except that no error checks are performed.

i also get the __pthread_mutex_cond_lock_adjust: Assertion (mutex->__data.__kind & 128) == 0' failed. error sometimes, after a long run.

So the error should be somewhere around here, still searching for it.

Thank you.

Upvotes: 0

Views: 394

Answers (3)

Mittous Issmail
Mittous Issmail

Reputation: 56

I don't know exactly what is your problem really is, but I think you have some misunderstanding with mutex and threads so ill explain to you some basic knowledge about mutex.

A mutex, in its most fundamental form, is just an integer in memory. This integer can have a few different values depending on the state of the mutex. When we speak of mutexes, we also need to speak about the locking operations. The integer in memory is not intriguing, but the operations around it are.

There are two fundamental operations which a mutex must provide:

lock
unlock

A thread wishing to use the mutex, must first call lock, then eventually call unlock to release it

so as I see in your code:

    for(int i = 80; i<= 8080; i++)
    {
        pthread_mutex_init(&mutexQueue,NULL);
        ...
        pthread_mutex_lock(&mutexQueue); //here you lock 'mutexQueue' so 'mutexQueue' need
                                         //to be unlocked so it can pass again the second
                                        //time, otherwise it gonna stop here forever.
        ...
        pthread_mutex_destroy(&mutexQueue);
    }

where you declare pthread_mutex_lock(&mutexQueue); normally your code must wait here forever until pthread_mutex_unlock(&mutexQueue); is called in the other tread then that thread can pass and lock the mutex again for the other treads and so on. You can check that website have some good information about threads https://mortoray.com/how-does-a-mutex-work-what-does-it-cost/ for me, I worked on a project called dining_philosopher_problem and it help me a lot to discover threads/mutex/sharing_memorie/process/semaphore/... you can check it here https://github.com/mittous/philosopher

Upvotes: 1

Useless
Useless

Reputation: 67733

Is there a problem to destroy the mutex and then re-init it after?

If something might still be using it, yes.

The code you showed is crazy: a shared queue's mutex should live as long as the queue it protects.

Further, the code you show acquires a lock and never unlocks. That doesn't make much sense either.

Upvotes: 2

John Carter
John Carter

Reputation: 6995

Are you unlocking the mutex? Destroying a locked mutex results in undefined behaviour:

The pthread_mutex_destroy() function shall destroy the mutex object referenced by mutex; the mutex object becomes, in effect, uninitialized. An implementation may cause pthread_mutex_destroy() to set the object referenced by mutex to an invalid value. A destroyed mutex object can be reinitialized using pthread_mutex_init(); the results of otherwise referencing the object after it has been destroyed are undefined.

phread_mutex_destroy

Upvotes: 2

Related Questions