Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix 多个读卡器和多个写卡器(我指的是多个)同步_Unix_Concurrency_Synchronization_Operating System_Locking - Fatal编程技术网

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时,这意味着无论谁首先持有锁,现在都可以释放它。唯一的不便是