Thread: Mutex

  1. #1
    Registered User
    Join Date
    Feb 2019
    Posts
    67

    Mutex

    Hey,

    I have the following question:

    As far as I know, as soon as a mutex is claimed with mutex_lock(), every other thread trying to execute mutex_lock() will wait until the mutex gets unclaimed and is unlocked again, then claim it.

    Is it possible to do the following:

    "If the mutex is claimed, wait, but if it is not, do not claim the mutex"

    Thank you!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,325
    Not in any atomically useful manner.

    pthread_mutex_lock(3): lock/unlock mutex - Linux man page
    You could build something out of pthread_mutex_trylock, but that would inevitably mess up in the presence of other threads.

    Perhaps explain why you would want to do such a thing.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Feb 2019
    Posts
    67
    Quote Originally Posted by Salem View Post
    Not in any atomically useful manner.

    pthread_mutex_lock(3): lock/unlock mutex - Linux man page
    You could build something out of pthread_mutex_trylock, but that would inevitably mess up in the presence of other threads.

    Perhaps explain why you would want to do such a thing.
    First Problem:

    Imagine a thread is reconfiguring an array.
    Imagine two other threads which need to read this array fastly but shall not block each other, but if the reconfiguring-thread is working, both arrays must not read the array....

    Second Problem (far bigger, but questions answer would not be a solution):
    Imagine a thread waiting for incoming clients with accept(). All socketfiledescriptor get saved in an array. What if in exactly this moment the array gets changed by an thread, which realizes that a socket has been closed and wants to remove the element out of the array.
    If I on the other side, make a mutexlock including accept. I am deadlocked until a new connection is coming in...

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,325
    > but if the reconfiguring-thread is working, both arrays must not read the array....
    So what's to stop the reconfigure thread from making changes half-way though a read?

    As in
    Code:
    // "If the mutex is claimed, wait, but if it is not, do not claim the mutex"
    if ( waitIfLockedElseCarryon() ) {
        // stuff
        // In another thread, reconfigure does pthread_mutex_lock successfully and changes the data
        // more stuff, now with a broken data structure.
    }
    Assuming the amount of overall work is non-trivial, the cost of a lock/unlock pair is (on my machine) of the order of 1uS.
    Code:
    #include <stdio.h>
    #include <errno.h>
    #include <pthread.h>
    #include <time.h>
    
    pthread_mutex_t mutex;
    
    int main()
    {
      if (pthread_mutex_init(&mutex, NULL) < 0) {
        perror("Could not initialize Mutex");
      }
    
      struct timespec t0,t1,t2,t3;
      clock_gettime(CLOCK_MONOTONIC, &t0);
      clock_gettime(CLOCK_MONOTONIC, &t1);
      pthread_mutex_lock(&mutex);
      clock_gettime(CLOCK_MONOTONIC, &t2);
      pthread_mutex_unlock(&mutex);
      clock_gettime(CLOCK_MONOTONIC, &t3);
    
      long clockread = t1.tv_nsec - t0.tv_nsec;
      long locktime = t2.tv_nsec - t1.tv_nsec;
      long unlocktime = t3.tv_nsec - t2.tv_nsec;
      printf("Overhead=%ld, lock=%ld, unlock=%ld\n", clockread, locktime, unlocktime);
    
      pthread_mutex_destroy(&mutex);
      return 0;
    }
    
    # These are nanosecond times.
    $ ./a.out 
    Overhead=206, lock=803, unlock=958
    $ ./a.out 
    Overhead=156, lock=784, unlock=665
    $ ./a.out 
    Overhead=190, lock=900, unlock=724
    $ ./a.out 
    Overhead=194, lock=734, unlock=710
    $ ./a.out 
    Overhead=161, lock=790, unlock=679
    > What if in exactly this moment the array gets changed by an thread, which realizes that a socket has been closed and wants to remove the element out of the array.
    I might design a different solution.

    Look, if you're using threads, you NEED a good design.
    Half-baked deployment of a thread here, or a lock there will just make a complete disaster you will never fully debug.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Feb 2019
    Posts
    67

    Talking

    Quote Originally Posted by Salem View Post
    > but if the reconfiguring-thread is working, both arrays must not read the array....
    So what's to stop the reconfigure thread from making changes half-way though a read?

    As in
    Code:
    // "If the mutex is claimed, wait, but if it is not, do not claim the mutex"
    if ( waitIfLockedElseCarryon() ) {
        // stuff
        // In another thread, reconfigure does pthread_mutex_lock successfully and changes the data
        // more stuff, now with a broken data structure.
    }
    Assuming the amount of overall work is non-trivial, the cost of a lock/unlock pair is (on my machine) of the order of 1uS.
    Code:
    #include <stdio.h>
    #include <errno.h>
    #include <pthread.h>
    #include <time.h>
    
    pthread_mutex_t mutex;
    
    int main()
    {
      if (pthread_mutex_init(&mutex, NULL) < 0) {
        perror("Could not initialize Mutex");
      }
    
      struct timespec t0,t1,t2,t3;
      clock_gettime(CLOCK_MONOTONIC, &t0);
      clock_gettime(CLOCK_MONOTONIC, &t1);
      pthread_mutex_lock(&mutex);
      clock_gettime(CLOCK_MONOTONIC, &t2);
      pthread_mutex_unlock(&mutex);
      clock_gettime(CLOCK_MONOTONIC, &t3);
    
      long clockread = t1.tv_nsec - t0.tv_nsec;
      long locktime = t2.tv_nsec - t1.tv_nsec;
      long unlocktime = t3.tv_nsec - t2.tv_nsec;
      printf("Overhead=%ld, lock=%ld, unlock=%ld\n", clockread, locktime, unlocktime);
    
      pthread_mutex_destroy(&mutex);
      return 0;
    }
    
    # These are nanosecond times.
    $ ./a.out 
    Overhead=206, lock=803, unlock=958
    $ ./a.out 
    Overhead=156, lock=784, unlock=665
    $ ./a.out 
    Overhead=190, lock=900, unlock=724
    $ ./a.out 
    Overhead=194, lock=734, unlock=710
    $ ./a.out 
    Overhead=161, lock=790, unlock=679
    > What if in exactly this moment the array gets changed by an thread, which realizes that a socket has been closed and wants to remove the element out of the array.
    I might design a different solution.

    Look, if you're using threads, you NEED a good design.
    Half-baked deployment of a thread here, or a lock there will just make a complete disaster you will never fully debug.
    I am not sure how your code relates to your answer nor to the problem? Could you make your intension clear? Thank you

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,325
    1. If you think that you can get away with not locking your data structure at all for reading, then you are mistaken.
    The lack of locks on read just means any write lock will immediately succeed and trample all over your read assumptions.

    2. The code illustrates that lock/unlock isn't that expensive, so your "need to read this array fastly" is hardly an impediment.

    You should concentrate on making the code RIGHT before you start worrying about making the code FAST.

    Nobody will care how FAST it is, if it keeps crashing when people try to use it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Feb 2019
    Posts
    441
    I recommend reading about pthread in depth. There are a bunch of synchorization objects you can use (rwlocks, mutexes, conditional objects, ...): Sun Multithread programming guide

    Another source is Advanced Programming in UNIX Environment by Richard W. Stevens

    Last edited by flp1969; 07-16-2019 at 09:31 AM.

  8. #8
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    640
    It sounds like you need a readers-writer lock. See functions that use the pthread_rwlock_t type.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mutex locks
    By Kennedy in forum Linux Programming
    Replies: 3
    Last Post: 02-12-2011, 01:26 PM
  2. need sugestion about mutex
    By quantt in forum Linux Programming
    Replies: 0
    Last Post: 08-21-2009, 08:35 AM
  3. Mutex question
    By laertius in forum C Programming
    Replies: 5
    Last Post: 09-17-2007, 12:16 PM
  4. Mutex in C
    By jgs in forum Windows Programming
    Replies: 4
    Last Post: 05-21-2005, 07:11 AM
  5. Mutex
    By DutchStud in forum Windows Programming
    Replies: 2
    Last Post: 11-06-2001, 12:09 AM

Tags for this Thread