首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pthread_mutex_lock/unlock的性能

pthread_mutex_lock/unlock的性能
EN

Stack Overflow用户
提问于 2011-06-24 04:59:41
回答 6查看 12.7K关注 0票数 11

我已经注意到,当我使用大量锁定和解锁线程的算法时,我会受到相当大的性能影响。

有什么方法可以帮助解决这个开销吗?使用信号量会提高/降低效率吗?

谢谢

代码语言:javascript
复制
typedef struct _treenode{
   struct _treenode *leftNode;
   struct _treenode *rightNode;
   int32_t data;
   pthread_mutex_t mutex;
}TreeNode;

pthread_mutex_t _initMutex = PTHREAD_MUTEX_INITIALIZER;

int32_t insertNode(TreeNode **_trunk, int32_t data){
   TreeNode **current;
   pthread_mutex_t *parentMutex = NULL, *currentMutex = &_initMutex;

   if(_trunk != NULL){
      current = _trunk;
      while(*current != NULL){
         pthread_mutex_lock(&(*current)->mutex);
         currentMutex = &(*current)->mutex;
         if((*current)->data < data){
            if(parentMutex != NULL)
               pthread_mutex_unlock(parentMutex);
            pthreadMutex = currentMutex;
            current = &(*current)->rightNode;
         }else if((*current)->data > data){
            if(parentMutex != NULL)
               pthread_mutex_unlock(parentMutex);
            parentMutex = currentMutex;
            current = &(*current)->leftNode;
         }else{
            pthread_mutex_unlock(currentMutex);
            if(parentMutex != NULL)
               pthread_mutex_unlock(parentMutex);
            return 0;
         }
      }
      *current = malloc(sizeof(TreeNode));
      pthread_mutex_init(&(*current)->mutex, NULL);
      pthread_mutex_lock(&(*current)->mutex);
      (*current)->leftNode = NULL;
      (*current)->rightNode = NULL;
      (*current)->data = data;
      pthread_mutex_unlock(&(*current)->mutex);
      pthread_mutex_unlock(currentMutex);
   }else{
      return 1;
   }
   return 0;
}

int main(){
   int i;
   TreeNode *trunk = NULL;
   for(i=0; i<1000000; i++){
      insertNode(&trunk, rand() % 50000);
   }
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-06-24 05:04:57

与其担心草叶,不如后退一步,观察整个森林。

任何依赖于两个线程的算法本质上都是低效的。试着找到一种方法来大大减少交互的需要。

例如,如果一个线程产生数据,而另一个线程使用它,那么很容易想到一个低效的算法,即生产者在共享内存中发布数据,然后等待另一个线程使用它。与此同时,消费者正在等待生产者完成,等等。生产者将数据写入文件或管道,消费者从文件或管道中读取数据,这一切都大大简化了。

票数 17
EN

Stack Overflow用户

发布于 2011-06-24 05:26:51

pthread_mutex_lockpthread_mutex_unlock的成本因争用而异:

  1. 单线程使用-要么只有一个线程存在,要么只有一个线程正在使用互斥锁和它保护的资源:几乎是空闲的,可能最多80-100个周期。
  2. 多线程使用资源,但锁持有的时间间隔非常短,争用很少:锁定有一些成本,而且很难衡量;成本主要包括使其他内核/ lock/unlock.

的缓存lines.

  • Significant锁争用无效:几乎每个锁定和解锁操作都需要内核的帮助,并且每个cpus的成本很容易达到几千(甚至数万)个周期

尽管如此,在大多数情况下和在大多数实现中,互斥锁应该是最便宜的锁定原语。有时,自旋锁的性能可能会更好。我从来不期望信号量表现得更好。

票数 15
EN

Stack Overflow用户

发布于 2011-06-24 05:41:13

据我所知,您的锁策略并不是最优的,因为大多数锁不会被用来更改数据,而只是用来读取和查找树中的路径。

pthread_rwlock_t可以在这方面提供帮助。您只需在树中向下的路径上获取读锁定,直到您遇到想要进行一些修改的节点。在那里,您将获得一个写锁。这样,当在不同的分支中遍历树时,您可以让其他线程执行相同的任务,而不会相互干扰。

一个不错的pthread_rwlock_t实现将通过一个计数器来实现这一点,只要不与写入者发生争用,它就会通过原子操作改变读取器。这应该是非常快的。我认为,一旦出现争用,它就会像互斥锁一样代价高昂。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6460542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档