我正在在嵌入式Linux OS(UClinux)上开发一个应用程序,我需要能够多次锁定MUTEX(通过同一线程)。

我有一个静音和一个静音的定义和初始化,如下所示:

pthread_mutexattr_t waiting_barcode_mutexattr;
pthread_mutex_t waiting_barcode_mutex;

pthread_mutexattr_init(&waiting_barcode_mutexattr);
pthread_mutexattr_settype(&waiting_barcode_mutexattr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&waiting_barcode_mutex, &waiting_barcode_mutexattr);

但是,当我尝试获得两次锁定时,它会阻止第二个锁:

pthread_mutex_lock(&waiting_barcode_mutex);
pthread_mutex_lock(&waiting_barcode_mutex);

我是将其初始化的,还是有更好的方法来实现同样的方法?

提前致谢。

结论:

  • 显然,pthread_mutex_recursive或pthread_mutex_recursive_np不起作用,因此我无法创建一个recentrant mutex。
  • try_lock也不好。如果可以的话,它将获取锁定并返回错误,如果无法获取锁定。不幸的是,该错误只是告诉我,静音已经在使用,我无法确定当前线程是否已经拥有锁。
  • 如果当前线程具有锁定,则PTHREAD_MUTEX_LOCK可以返回错误,但是为此,我需要创建一个类型的pthread_mutex_errorcheck的静音,我也不能创建一个。
有帮助吗?

解决方案 5

(只是意识到我没有将这个问题标记为回答)

从问题的结论中得出:

  • 显然,pthread_mutex_recursive或pthread_mutex_recursive_np不起作用,因此我无法创建一个recentrant mutex。
  • try_lock也不好。如果可以的话,它将获取锁定并返回错误,如果无法获取锁定。不幸的是,该错误只是告诉我,静音已经在使用,我无法确定当前线程是否已经拥有锁。
  • 如果当前线程具有锁定,则PTHREAD_MUTEX_LOCK可以返回错误,但是为此,我需要创建一个类型的pthread_mutex_errorcheck的静音,我也不能创建一个。

其他提示

这不是您期望的吗?

第一个呼叫获取锁,第二个电话将阻止直到释放第一个锁(pthread_mutex_unlock)。这就是锁做的。

从文档中:

“如果静音已经锁定,则调用线块,直到静音可用。”

也许你想要 pthread_mutex_trylock?除非我们知道您要完成的工作,否则很难说。

更正:

我没有看到您正在设置pthread_mutex_recursive ....让我再考虑一下。

思考之后:

从围绕Google Codesearch进行戳,看起来PTHREAD_MUTEX_RECURSIVE均未在所有libs中实现。您可以尝试pthread_mutex_recursive_np,或者您可能会做一些奇特的事情来解决这个问题。

听起来像是pthread Mutex并不是重新进入。您可以用标志来解决此问题,指示您的线程是否已经锁定了互斥符:

bool haveLock = false;// thread variable
pthread_mutex_t waiting_barcode_mutex; // also thread var

mylock()
{
   if( haveLock ) return; // no need to lock twice
   pthread_mutex_lock(&waiting_barcode_mutex);
   haveLock = true;
}

myunlock()
{
   haveLock = false;
   pthread_mutex_unlock(&waiting_barcode_mutex); // or whatever the unlock call is
}

这是在我的Dell M6300上的Ubuntu 12.04 LTS上测试的工作代码:

  pthread_mutex_t mutex;
  pthread_mutexattr_t attr;
  int rc = pthread_mutexattr_init(&attr);
    if (rc != 0)
        throw (L"pthread_mutexattr_init returns " + rc);
    rc = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE_NP);
    if (rc != 0)
        throw (L"pthread_mutexattr_settype returns " + rc);
    rc = pthread_mutex_init (&mutex, &attr);
    if (rc != 0)
        throw (L"pthread_mutex_init returns " + rc);
    rc = pthread_mutexattr_destroy(&attr);
    if (rc != 0)
        throw (L"pthread_mutexattr_destroy returns " + rc);

   //first lock
   rc = pthread_mutex_lock(&mutex);
    if (rc != 0)
        throw (L"pthread_mutex_lock returns " + rc);
   //second lock
   rc = pthread_mutex_lock(&mutex);
    if (rc != 0)
        throw (L"pthread_mutex_lock returns " + rc);

不要忘记释放静音的次数多次。

下面的代码表明,在调用pthread上的解锁之前,锁定关键部分两次或三次或n次没有问题。您可以在不用担心的情况下连续解锁之前连续地在同一线程上执行多个锁,但请注意,这不是一个好的程序员的练习。正确的方法是调用lock(),让线程执行关键部分并调用Unlock(),以便其他线程可以在锁定和解锁之间执行相同的代码(称为临界部分)。下面的代码可以使用PTHread上的属性来防止任何程序员的不幸)。

阅读!

// Example program using a thread locking multiple times sequentially before unlocking
#include <iostream>

using namespace std;

pthread_mutexattr_t     _attr;
pthread_mutex_t         _mutex;

///
/// Initialize mutex with error return locking mechanism (does not block
/// its own thread if multiple locks occurs.
///
void InitMutex()
{
   // Initialize mutex
   int ret=0;
   ret = pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_ERRORCHECK_NP);   // PTHREAD_MUTEX_ERRORCHECK_NP avoids double locking on same thread.
   if(ret != 0)
   {
      printf("Mutex attribute not initialized!!\n");
   }
   ret = pthread_mutex_init(&_mutex, &_attr);
   if(ret != 0)
   {
      printf("Mutex not initialized!!\n");
   }
}

///
/// Locks the critical section
///
int lock_me()
{
   return pthread_mutex_lock(&_mutex);
}

///
/// Unlocks the critical section
///
int unlock_me()
{
   return pthread_mutex_unlock(&_mutex);
}

int main()
{
  InitMutex(); // Very important
  int ret = 0;

  ret = lock_me();    // return value of 0 - OK
  cout << "First lock returns: "<< ret<< endl;
  ret = lock_me();    // returns a value like 35 - ERROR, but ignores locking again
  cout << "Second lock returns: "<< ret<< endl;

  // Do something in this critical section. No other thread can execute this at this time before unlock. Other threads (if any) wait at lock() waiting for main function to unlock() first.

  ret = unlock_me();  // unlocks the critical section. All is OK
  cout << "First unlock returns: "<< ret<< endl;
  ret = unlock_me();  // returns error value of 1, nothing to lock
  cout << "Second unlock returns: "<< ret<< endl;
  ret = unlock_me();  // same as above, nothing to do. Ignore and move on!
  cout << "Third unlock returns: "<< ret << endl;

  // The main() thread will never have a race condition ;) All iz well!!

  pthread_mutexattr_destroy(&_attr);    // clean up the mutex attribute
  pthread_mutex_destroy(&_mutex);       // clean up the mutex itself

}

输出:

第一个锁返回:0

第二锁回报:35

第一个解锁回报:0

第二个解锁回报:1

第三个解锁回报:1

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top