Unix 多个读卡器和多个写卡器(我指的是多个)同步
我正在开发一个功能,它需要一个读/写锁的变体,可以允许并发多个写入程序 标准读/写锁允许多个读卡器或单个写卡器同时运行。我需要一个变量,可以允许多个读者或多个作家同时进行。因此,它不应该允许读者和作者同时出现。但是,允许同时有多个作者或多个读者是可以的 我希望我是清楚的。到目前为止,我找不到任何现有的算法。我可以通过排队等方式想出几种方法来实现这一点。但是,我不想冒险自己去做,除非根本不存在 你们知道现有的计划吗Unix 多个读卡器和多个写卡器(我指的是多个)同步,unix,concurrency,synchronization,operating-system,locking,Unix,Concurrency,Synchronization,Operating System,Locking,我正在开发一个功能,它需要一个读/写锁的变体,可以允许并发多个写入程序 标准读/写锁允许多个读卡器或单个写卡器同时运行。我需要一个变量,可以允许多个读者或多个作家同时进行。因此,它不应该允许读者和作者同时出现。但是,允许同时有多个作者或多个读者是可以的 我希望我是清楚的。到目前为止,我找不到任何现有的算法。我可以通过排队等方式想出几种方法来实现这一点。但是,我不想冒险自己去做,除非根本不存在 你们知道现有的计划吗 谢谢,如果您正在使用pthreads,请查看中的同步方法 您可以对两个变量read
谢谢,如果您正在使用pthreads,请查看中的同步方法 您可以对两个变量
readerCount
和writerCount
以及一个互斥量使用类似的方法。
在读卡器线程中,您将锁定互斥锁并等待writecount==0
。如果满足此条件,则将读取器计数增加1并释放锁。然后你做阅读。完成后,再次锁定互斥锁,减小读取器计数,发出条件更改信号并释放锁
writer线程遵循相同的逻辑,但等待条件
readerCount==0
并增加/减少writerCount
。如果使用pthreads,请查看中的同步方法
您可以对两个变量readerCount
和writerCount
以及一个互斥量使用类似的方法。
在读卡器线程中,您将锁定互斥锁并等待writecount==0
。如果满足此条件,则将读取器计数增加1并释放锁。然后你做阅读。完成后,再次锁定互斥锁,减小读取器计数,发出条件更改信号并释放锁
writer线程遵循相同的逻辑,但等待条件
readerCount==0
,然后递增/递减writerCount
。我确实有一个解决方案,可以使用nifs注释。我已经在下面发布了我的解决方案。问题在于公平政策。饥饿很容易发生。在我的方法中,一种线程比另一种线程的可能性小。所以,我只是把女孩放在第一位。理想情况下,我们希望这是一些体面的公平政策
/**
* RestRoomLock:
*
* This lock tries to simulate a gender based access to common rest room.
* It is okay to have multiple boys or multiple girls inside the room. But,
* we can't have boys and girls at the same time inside the room.
*
* This implementation doesn't really have proper fairness policy. For now,
* girls are being treated with priority as long as boys are being gentle,
* boyEntryBeGentle();
*
* @author bmuppana
*/
public class RestRoomLock {
int boysInside;
int girlsInside;
int girlsWaiting;
RestRoomLock() {
boysInside = girlsInside = girlsWaiting = 0;
}
public synchronized void boyEntry() {
while (girlsInside > 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boysInside++;
}
public synchronized void boyEntryBeGentle() {
while (girlsInside + girlsWaiting > 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boysInside++;
}
public synchronized void boyExit() {
boysInside--;
assert boysInside >= 0;
notifyAll();
}
public synchronized void girlEntry() {
girlsWaiting++;
while (boysInside > 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
girlsWaiting--;
girlsInside++;
}
public synchronized void girlExit() {
girlsInside--;
assert girlsInside >= 0;
notifyAll();
}
}
根据nifs的评论,我确实有一个解决方案。我已经在下面发布了我的解决方案。问题在于公平政策。饥饿很容易发生。在我的方法中,一种线程比另一种线程的可能性小。所以,我只是把女孩放在第一位。理想情况下,我们希望这是一些体面的公平政策
/**
* RestRoomLock:
*
* This lock tries to simulate a gender based access to common rest room.
* It is okay to have multiple boys or multiple girls inside the room. But,
* we can't have boys and girls at the same time inside the room.
*
* This implementation doesn't really have proper fairness policy. For now,
* girls are being treated with priority as long as boys are being gentle,
* boyEntryBeGentle();
*
* @author bmuppana
*/
public class RestRoomLock {
int boysInside;
int girlsInside;
int girlsWaiting;
RestRoomLock() {
boysInside = girlsInside = girlsWaiting = 0;
}
public synchronized void boyEntry() {
while (girlsInside > 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boysInside++;
}
public synchronized void boyEntryBeGentle() {
while (girlsInside + girlsWaiting > 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boysInside++;
}
public synchronized void boyExit() {
boysInside--;
assert boysInside >= 0;
notifyAll();
}
public synchronized void girlEntry() {
girlsWaiting++;
while (boysInside > 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
girlsWaiting--;
girlsInside++;
}
public synchronized void girlExit() {
girlsInside--;
assert girlsInside >= 0;
notifyAll();
}
}
您正在寻找的概念是可重入锁。您需要能够尝试获取锁,并且如果锁已被获取,则不会被阻止(这称为可重入锁)。java中有一个可重入锁的本机实现,因此我将用java演示这个示例。() 因为在使用tryLock()时,如果锁不可用,您不会被阻止,您的编写器/读取器可以继续。但是,只有在确定没有人在读/写时才需要释放锁,因此需要保持读/写者的计数。您需要同步此计数器,或者使用允许原子递增/递减的本机atomicInteger。对于这个例子,我使用了原子整数
Class ReadAndWrite {
private ReentrantLock readLock;
private ReentrantLock writeLock;
private AtomicInteger readers;
private AtomicInteger writers;
private File file;
public void write() {
if (!writeLock.isLocked()) {
readLock.tryLock();
writers.incrementAndGet(); // Increment the number of current writers
// ***** Write your stuff *****
writers.decrementAndGet(); // Decrement the number of current writers
if (readLock.isHeldByCurrentThread()) {
while(writers != 0); // Wait until all writers are finished to release the lock
readLock.unlock();
}
} else {
writeLock.lock();
write();
}
}
public void read() {
if (!readLock.isLocked()) {
writeLock.tryLock();
readers.incrementAndGet();
// ***** read your stuff *****
readers.decrementAndGet(); // Decrement the number of current read
if (writeLock.isHeldByCurrentThread()) {
while(readers != 0); // Wait until all writers are finished to release the lock
writeLock.unlock();
}
} else {
readLock.lock();
read();
}
}
这里发生了什么:首先检查锁是否已锁定,以确定是否可以执行要执行的操作。如果它被锁定,则意味着您无法读取或写入,因此您可以使用lock将自己置于等待状态,并在再次释放锁时重新调用相同的操作
如果未锁定,则使用tryLock锁定其他操作(如果要读取,则锁定写入,反之亦然)。tryLock不会阻止它是否已被锁定,因此多个写入程序可以同时写入,多个读卡器可以同时读取。当执行与您相同操作的线程数达到0时,这意味着无论谁首先持有锁,现在都可以释放它。此解决方案唯一的不便之处在于,持有锁的线程必须保持活动状态,直到所有人都完成释放为止。您要寻找的概念是可重入锁。您需要能够尝试获取锁,并且如果锁已被获取,则不会被阻止(这称为可重入锁)。java中有一个可重入锁的本机实现,因此我将用java演示这个示例。() 因为在使用tryLock()时,如果锁不可用,您不会被阻止,您的编写器/读取器可以继续。但是,只有在确定没有人在读/写时才需要释放锁,因此需要保持读/写者的计数。您需要同步此计数器,或者使用允许原子递增/递减的本机atomicInteger。对于这个例子,我使用了原子整数
Class ReadAndWrite {
private ReentrantLock readLock;
private ReentrantLock writeLock;
private AtomicInteger readers;
private AtomicInteger writers;
private File file;
public void write() {
if (!writeLock.isLocked()) {
readLock.tryLock();
writers.incrementAndGet(); // Increment the number of current writers
// ***** Write your stuff *****
writers.decrementAndGet(); // Decrement the number of current writers
if (readLock.isHeldByCurrentThread()) {
while(writers != 0); // Wait until all writers are finished to release the lock
readLock.unlock();
}
} else {
writeLock.lock();
write();
}
}
public void read() {
if (!readLock.isLocked()) {
writeLock.tryLock();
readers.incrementAndGet();
// ***** read your stuff *****
readers.decrementAndGet(); // Decrement the number of current read
if (writeLock.isHeldByCurrentThread()) {
while(readers != 0); // Wait until all writers are finished to release the lock
writeLock.unlock();
}
} else {
readLock.lock();
read();
}
}
这里发生了什么:首先检查锁是否已锁定,以确定是否可以执行要执行的操作。如果它被锁定,则意味着您无法读取或写入,因此您可以使用lock将自己置于等待状态,并在再次释放锁时重新调用相同的操作
如果未锁定,则使用tryLock锁定其他操作(如果要读取,则锁定写入,反之亦然)。tryLock不会阻止它是否已被锁定,因此多个写入程序可以同时写入,多个读卡器可以同时读取。当执行与您相同操作的线程数达到0时,这意味着无论谁首先持有锁,现在都可以释放它。唯一的不便是