CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Oct 2001
    Posts
    745

    Linux Mutex Problem-Could anyone help

    I have a multithreaded application running under Linux.
    When Iam Debugging I have another problem ,Iam getting a Deadlock

    I have implemented the LinuxMutex class as follows:

    LinMutex::LinMutex()
    {
    pthread_mutex_init(&m_hMutex,(pthread_mutexattr_t*)NULL);

    }
    void LinMutex::AcquireLock()
    {
    pthread_mutex_lock(&m_hMutex);
    }

    void LinMutex::ReleaseLock()
    {
    pthread_mutex_unlock(&m_hMutex);
    }

    LinMutex::~LinMutex()
    {
    pthread_mutex_destroy(&m_hMutex);

    }

    Is it alright.I heard from a colleuge,that If a thread which already owns a Mutex,Try to access,it again there will be a deadlock under Linux.

    In windows,I have implemented the lock() as follows to remove the DeadLock as said in Msdn:
    // from Msdn
    The thread that owns a mutex can specify the same mutex in repeated wait function calls without blocking its execution. Typically, you would not wait repeatedly for the same mutex, but this mechanism prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex once for each time that the mutex satisfied a wait.

    void WinMutex::AcquireLock()
    {
    while (WaitForSingleObject(m_hMutex,1000L)!= WAIT_OBJECT_0);
    }


    What should I do to remove the Deadlock.What should be done in The AcquireLock() of LinMutex.
    Could anyone help me on this regard.....

  2. #2
    Join Date
    Jun 2002
    Location
    Letchworth, UK
    Posts
    1,020
    pthread_mutex_lock will block the thread until it acquires the lock. If the thread already has the mutex, obtaining it again will cause deadlock.

    Try this. It used to work on Solaris and HPUX.

    In LinMutex, add the variables

    pthread_t mSelfish;
    int mLocks;
    Code:
    LinMutex::LinMutex()
    {
        pthread_mutex_init(&m_hMutex,(pthread_mutexattr_t*)NULL);
        mSelfish = 0;
        mLocks = 0;
    }
    void LinMutex::AcquireLock()
    {
        if (mSelfish == pthread_self ())
        {
            mLocks++;
        }
        else
        {
            pthread_mutex_lock(&m_hMutex);
            mSelfish = pthread_self ();
            mLocks = 1;
        }    
    }
    
    void LinMutex::ReleaseLock()
    {
        if (mSelfish == pthread_self ())
        {
            if (--mLocks == 0)
            {
                mSelfish = 0;
                pthread_mutex_unlock(&m_hMutex);
            }
        }
    }
    This assumes that the number of acquires == the number of releases. If it doesn't, you still get deadlocked. The way I prefer to code it is to use the out-of-scope destructor technique. There may be some fancy name for this technique that I've been using for the last 9 years.
    Code:
    class LockIt
    {
        static pthread_mutex_t mMutex;
        static bool mUnknown;
        static pthread_t mSelfish;
        static int mCount;
    public:
        Lockit ()
        {
            if (mUnknown)
            {
                mUnknown = false;
                pthread_mutex_init ((&mMutex,(pthread_mutexattr_t*)NULL);
                mSelfish = 0;
                mCount = 0;
            }
            if (mSelfish != pthread_self ())
            {
                pthread_mutex_lock(&mMutex);
                mSelfish = pthread_self ();
            }
            mCount++;
        }
        ~Lockit ()
        {
            mCount--;
            if (mCount == 0)
            {
                 pthread_mutex_unlock (&mMutex);
            }
        }
    };
    // Static declarations
    pthread_mutex_t Lockit::mMutex;
    bool Lockit::mUnknown = true;
    pthread_t Lockit::mSelf = 0;
    int Lockit::mCount = 0;
    
    // Simple routine using the mutex lock
    void Critical ()
    {
        Lockit sema;
    
        // do whatever
    
        // Natural destructor when sema goes out of scope so you
        // don't even have to delete it.
    }
    It is just so much neater not having to worry about unlocking.
    Succinct is verbose for terse

  3. #3
    Join Date
    Oct 2001
    Posts
    745

    Thanks

    Hi,
    Thank you very Much for that piece of code & for ur valuable suggestion.It was really helpful for me.Thanks a lot.
    I will send u personal messages when ever I have some problems in Linux ,if u dont mind

  4. #4
    Join Date
    Sep 2002
    Location
    Belarus - Tirol, Austria
    Posts
    647
    It's also most easy way for U.
    Linux support some kind of mutexes.
    The mutex kind determines what happens if a thread attempts to lock a mutex it already owns with pthread_mutex_lock.

    There are next kinds:
    PTHREAD_MUTEX_FAST_NP - fast mutex ( it's by default ) this mutex deadlock your thread if it try to lock mutex it already owns.
    PTHREAD_MUTEX_RECURSIVE_NP - recursive mutex
    this mutex has internal counter of locks and it
    don't deadlock the thread. thread_mutex_lock
    simply return OK status if you try to lock mutex it already owns.
    PTHREAD_MUTEX_ERRORCHECK_NP - else like PTHREAD_MUTEX_RECURSIVE_NP but return error status.

    so you mast write:

    pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

    or use

    pthread_mutexattr_init() and pthread_mutexattr_setkind_np functions to set PTHREAD_MUTEX_RECURSIVE_NP kind for mutex.
    "UNIX is simple; it just takes a genius to understand its simplicity!"

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured