随笔-并行编程-记一次锁review过程

同事对读写锁增加了一个支持嵌套的功能

原先的问题:

1、同一个线程已经获取到写锁,再去上一次写锁就会卡死; (重复上read lock不会有问题)

解决方式:

1、上写锁时保存当前代码流的thread-id,锁虽然会被多个线程拿,但是上写锁是唯一的,所以某一时刻只会被某个线程持有
2、当前线程代码流继续向下执行碰到需要lock-write、lock-read、unlock-read都不执行(thread-id不会随着核的转移而改变,所以还是在同一个线程)
3、针对unlock-write还要加一个记录lock-write调用深度,保证是在最后一个解写锁的时候才去做真正的解写锁, 如

lock-write-1
  lock-write-2
  unlock-write-2
unlock-write-1

如果没有记录深度,在unlock-write-2时候退出写锁,也就失去了保护;

具体改法:

 typedef struct {
     pthread_rwlock_t rwlock;
+    pthread_t owner_threadid;
+    int wt_lock_depth;
 } x_rwlock;

/* 上写锁时保存thread-id ,当前线程已经上过锁的再尝试上写锁不做任何操作 */
@@ -187,10 +205,19 @@ int x_rwlock_lock_write(
 {
+    if (pthread_self() == xlk->owner_threadid) {
+        xlk->wt_lock_depth++;
+        return 0;
+    }
     if (pthread_rwlock_wrlock(&xlk->rwlock) != 0) {
         return -1;
     }
+    xlk->owner_threadid = pthread_self();

/* lock-read unlock-read 判断已经上了写锁,不用再进行什么操作 */
@@ -140,6 +142,14 @@ int x_rwlock_lock_read(
 {
+    pthread_t cur = pthread_self();
+    if (cur == xlk->owner_threadid) {
+        return 0;
+    }
     if (pthread_rwlock_rdlock(&xlk->rwlock) != 0) {

@@ -164,6 +174,14 @@ int x_rwlock_unlock_read(
{
+    pthread_t cur = pthread_self();
+    if (cur == xlk->owner_threadid) {
+        return 0;
+    }
     if (pthread_rwlock_unlock(&xlk->rwlock) != 0) {

/* unlock-write 仅发生在拿到锁的线程才去调用(处于防御性编码还是加了一下),仅需要判断上write lock的深度  */
@@ -211,10 +238,19 @@ int x_rwlock_unlock_write(
+    if (pthread_self() == xlk->owner_threadid && xlk->wt_lock_depth > 0) {
+        xlk->wt_lock_depth--;
+        return 0;
+    }
     if (pthread_rwlock_unlock(&xlk->rwlock) != 0) {
         return -1;
     }
+    xlk->owner_threadid = 0;

上面的实现有个问题,你看出来了吗?

点击查看代码

posted @ 2024-03-15 17:50  LiYanbin  阅读(1)  评论(0编辑  收藏  举报