c-在读/写线程中使用信号量



我有一个问题,我有多个线程(读取线程(要读取共享数据,到目前为止没有问题。此共享数据将在另一个单个线程(写入线程(中更新。

在写入期间,不应进行任何读取以防止数据损坏。

我最初的想法是在阅读之后使用一个信号量(Posix信号量(。

使用sem_wait((和sem_post((可以很好地阻塞、减少和增加读取线程内的信号量。只要信号量不为0,sem_wait((就不会阻塞并允许线程读取数据。

我的问题从这里开始。现在,我想让写线程的条件与sem_wait((的实际操作相反。只要信号量大于零,我就希望写线程被阻塞,因为这意味着有一个读线程正在进行中。

当信号量大于0时,有什么方法可以阻止它吗?或者有什么不同的方法可以解决这个问题吗?

谢谢!

一个选项是使用POSIX读写锁,除非有写入程序,否则多个读卡器可以获取该锁。

另一种选择是较低级别的seqlock,但它可能更难正确实现和使用,因为它需要很好地掌握内存模型数据竞赛和内存顺序。

如果你必须使用信号量,并且处于unix-y类型的环境中,我认为你会遇到这样的问题:

typedef struct rwl RWL;
struct rwl {
sem_t  lock;
sem_t  wread;
sem_t  wwrite;
int    nreaders;
int    nwriters;
};

void RWL_REnter(RWL *l) {
while (1) {
sem_wait(&l->lock);
l->nreaders++;
if (l->nwriters) {
sem_post(&l->lock);
sem_wait(&l->wread);
} else {
sem_post(&l->lock);
break;
}
}
}
void RWL_WEnter(RWL *l) {
while (1) {
sem_wait(&l->lock);
l->nwriters++;
if (l->nreaders || l->nwriters > 1) {
sem_post(&l->lock);
sem_wait(&l->wwrite);
} else {
sem_post(&l->lock);
break;
}
}
}
void RWL_WExit(RWL *l) {
sem_wait(&l->lock);
if (--(l->nwriters)) {
sem_post(&l->wwrite);
} else while (l->nreaders--) {
sem_post(&l->wread);
}
sem_post(&l->lock);
}
void RWL_RExit(RWL *l) {
sem_wait(&l->lock);
if (--(l->nreaders)) {
sem_post(&l->wread);
} else if (l->nwriters--) {
sem_post(&l->wwrite);
}
sem_post(&l->lock);
}

从功能上讲,锁是结构的互斥体,wwrite、wread分别作为编写器和读取器的条件变量。nreaders需要记住有多少并发读卡器(因为你不能等待+tive信号量(,nwriters需要记住有有多少写卡器在等待[你不想在任何一种情况下盲目发帖]。

最新更新