【发布时间】:2018-08-09 09:10:52
【问题描述】:
我目前正在阅读 APUE 这本书。当我阅读 pthread reader/writer-lock 的章节时,我有一个关于它使用 reader/writer-lock 实现并发队列的问题。
struct queue {
struct job *q_head;
struct job *q_tail;
pthread_rwlock_t q_lock;
};
/*
* Remove the given job from a queue.
*/
void
job_remove(struct queue *qp, struct job *jp)
{
pthread_rwlock_wrlock(&qp->q_lock);
if (jp == qp->q_head) {
qp->q_head = jp->j_next;
if (qp->q_tail == jp)
qp->q_tail = NULL;
else
jp->j_next->j_prev = jp->j_prev;
} else if (jp == qp->q_tail) {
qp->q_tail = jp->j_prev;
jp->j_prev->j_next = jp->j_next;
} else {
jp->j_prev->j_next = jp->j_next;
jp->j_next->j_prev = jp->j_prev;
}
pthread_rwlock_unlock(&qp->q_lock);
}
我的问题是,这个实现如何确保 struct job 只从链表中删除一次。据我了解,可以安排两个线程,使它们就在pthread_rwlock_wrlock 行之前。然后struct job *jp 可能会被释放两次。如果struct job * 是动态分配的数据结构,这可能会导致双重释放错误。有什么建议吗?
【问题讨论】:
-
“两个线程可以在 pthread_rwlock_wrlock 行之前停止”是什么意思?为什么线程会停止?
-
我的意思是这些线程可以被调度,以便两个线程都运行到那个步骤。
-
您必须查看
pthread_rwlock_wrlock的源代码,但我的猜测是有一个 if 语句可以检查锁是否已设置或可用。这应该相当于一条机器指令,这意味着这是一个线程获得锁的地方,而另一个线程将不得不等到锁被释放。 -
发布的代码可能无法编译。它在
else if (jp == qp->q_tail)之前缺少一个右括号。
标签: c concurrency linked-list readwritelock