如何正确销毁pthread互斥锁 [英] How to correctly destroy pthread mutex

查看:799
本文介绍了如何正确销毁pthread互斥锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我究竟如何才能销毁pthread互斥变量?

How exactly i can destroy a pthread mutex variable ?

这就是我想要做的. 我想缓存对象(结构变量),按键查找. 我希望在这里具有最小的锁粒度.所以我想每个都有一个锁 对象可能嵌入在结构中,以便我可以进行对象级锁定.

Here is what i want to do. I want to have objects (structure variables) cached , which are looked up by key. I want to have minimum granularity of locks here. So i want to have a lock for each object probably embedded in the structure so that i can have object level locking.

现在的问题是如何安全地销毁这些物体? 看起来第一步是从查找表中删除该对象,以使该对象不会 将来可以访问.

Now the problem is how to safely destroy these objects ? Looks like first step is to remove the object from the lookup table so that the object is not accessible in future that is fine.

我想从缓存中释放对象. 现在如何正确销毁/释放互斥锁? pthread_mutex_destroy文档说互斥锁处于锁定状态时,我们不应使用pthread_mutex_destroy.假设某个线程决定销毁它需要销毁的对象 锁,以便释放锁并执行pthread_mutex_destroy.其他等待对象锁定的线程会怎样?

I want to free the object from the cache. Now how to destroy/free mutex correctly ? pthread_mutex_destroy document says we should not use the pthread_mutex_destroy while the mutex is locked. Lets say a thread decides to destroy the object it needs to destroy the lock so it releases the lock and does a pthread_mutex_destroy. What happens to the other threads waiting for the objects lock ?

以下是模拟以上代码的代码,请注意,我使用sleep(2)放大了 种族.

Here is the code to simulate the above , note i used sleep(2) to magnify the effect of race .

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

typedef struct exampleObj {
   pthread_mutex_t mutex;
   int key;
   int value1;
   int value2;
}exampleObj;

exampleObj sharedObj = {PTHREAD_MUTEX_INITIALIZER,0,0,0};

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 

exampleObj* Lookup(int key) {
   return &sharedObj;
}

void* thrFunc(void* id) {
   int i = (*((int*)id));
   char errBuf[1024];
   exampleObj * obj = Lookup(0);

   if (pthread_mutex_lock(&obj->mutex)) {
      printf("Locking failed %d \n",i);
      return NULL;
   }
   // Do something
   printf("My id %d will do some work for 2 seconds.\n",i);
   sleep(2);
   pthread_mutex_unlock(&obj->mutex);
   int errNum = pthread_mutex_destroy(&obj->mutex);
   strerror_r(errNum,errBuf,1024);
   printf("Destroying mutex from thread %d : %s\n ",errNum,errBuf);
   return NULL;
}

int main() {
   pthread_t thrds[10];
   int i;
   int args[10];
   char errBuf[1024];
   int errNum = 1;

   for (i=0;i<10;i++){
      args[i] = i;
      pthread_create(&thrds[i],NULL,thrFunc,args+i);
   }

   for (i=0;i<10;i++){
      pthread_join(thrds[i],NULL);
   }
   return 0;
}

多个线程成功破坏了互斥锁.其余线程永远挂起. Gdb显示那些线程正在等待锁.

Multiple threads succeeds in destroying the mutex. And the remaining threads hang for ever. Gdb shows those threads are waiting for the lock.

推荐答案

您遇到的基本问题是,从缓存中删除对象需要在缓存级别而不是对象级别进行同步.

The basic problem you have is that removing an object from the cache is something that requires synchronisation at the cache level, not the object level.

实现此目的的一种方法是对整个缓存具有全局锁定,该锁定仅在查找期间保留,并在获取对象锁定后将其丢弃.该锁可以是读写器锁,仅在线程要删除对象时才用于写入.因此,一个希望使用缓存对象的线程可以这样做:

One way to implement this is by having a global lock for the entire cache that is only held during lookups, and is dropped once the object lock has been acquired. This lock can be a reader-writer lock, held for writing only if a thread is going to remove the object. So a thread that wishes to use a cache object would do:

pthread_rwlock_rdlock(&cache_lock);
exampleObj * obj = Lookup(key);
pthread_mutex_lock(&obj->mutex);
pthread_rwlock_unlock(&cache_lock);

/* Do some work on obj */

pthread_mutex_unlock(&obj->mutex);

和一个希望破坏缓存对象的线程可以:

and a thread that wishes to destroy a cache object would do:

pthread_rwlock_wrlock(&cache_lock);
exampleObj * obj = Lookup(key);
pthread_mutex_lock(&obj->mutex);
Remove(key);
pthread_rwlock_unlock(&cache_lock);

/* Do some cleanup work on obj */
pthread_mutex_unlock(&obj->mutex);
pthread_mutex_destroy(&obj->mutex);

(其中Remove()函数将其从缓存中删除,因此后续的Lookup()函数无法将其返回).

(where the Remove() function removes the function from the cache so that subsequent Lookup() functions cannot return it).

这篇关于如何正确销毁pthread互斥锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆