1

동시 다중 기록기를 허용 할 수있는 읽기/쓰기 잠금 변형이 필요한 기능을 개발 중입니다.다중 판독기 및 다중 기록기 (다중 의미) 동기화

표준 읽기/쓰기 잠금은 다중 판독기 또는 단일 기록기를 동시에 실행할 수있게합니다. 여러 명의 독자 또는 여러 명의 작성자를 동시에 허용 할 수있는 변형이 필요합니다. 따라서 리더와 작가를 동시에 허용해서는 안됩니다. 하지만 동시에 여러 작가를 동시에 허용하거나 여러 독자를 허용하는 것이 좋습니다.

나는 분명히했으면 좋겠다. 지금까지 기존 알고리즘을 찾을 수 없었습니다. 몇 가지 대기열 등을 사용하여이 작업을 수행하는 몇 가지 방법을 생각해 볼 수는 있지만, 존재하지 않는 한 직접 수행하지 않아도됩니다.

기존 구성표를 아십니까?

감사합니다,

+0

두 개의 읽기/쓰기 잠금으로 뭔가를 할 수있는 것처럼 느껴집니다. 그러나 나는 그것을 완전히 풀 수는 없었다. – APKar

답변

0

당신의 pthreads를 사용하는 경우, this question의 동기화 방법을 살펴.

두 가지 변수 readerCountwriterCount과 뮤텍스를 사용하여 유사한 접근 방식을 사용할 수 있습니다. 독자 스레드에서 뮤텍스를 잠그고 writerCount == 0을 기다립니다. 이 조건이 충족되면 readerCount을 1 씩 증가시키고 잠금을 해제합니다. 그럼 당신은 독서를합니다. 완료되면 mutex를 다시 잠그고 readerCount을 감소시키고 조건 변경을 신호하고 잠금을 해제하십시오.

라이터 스레드는 동일한 논리를 따르지 만 조건 readerCount == 0을 기다리고 대신 writerCount을 증가/감소시킵니다.

+0

감사 nif. 나는 그 라인을 따라 생각하고 있었다. 위의 내 대답을 게시했습니다. 문제는 공정성 정책에 있습니다. – APKar

0

나는 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(); 
    } 
} 
0

당신이 찾고있는 개념은 재진입 잠금입니다. 잠금을 획득하려고 시도 할 수 있어야하며 잠금이 이미 수행 된 경우 차단되지 않아야합니다 (이를 재진입 잠금이라고 함). Java에서이 예제를 설명 할 것이므로 Java에서 재진입 가능 잠금의 기본 구현이 있습니다. (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html).

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(); 
    } 
    } 

여기에 무슨 일 : 잠금이 당신이 수행하기 위하여려고하고있는 작업을 수행 할 수 있는지 알고 잠긴 경우 먼저 확인할. 잠긴 경우에는 읽거나 쓸 수 없으므로 잠금을 사용하여 대기 상태가되고 잠금이 다시 해제 될 때 동일한 작업을 다시 호출합니다.

잠긴 상태가 아니라면 tryLock을 사용하여 다른 작업 (잠금 쓰기를 읽으려는 경우 또는 그 반대의 경우)을 잠급니다. tryLock은 이미 잠겨 있어도 차단하지 않으므로 여러 작성자가 동시에 작성하고 여러 독자가 동시에 읽을 수 있습니다.당신이 0에 도달 한 것과 같은 일을하는 쓰레드의 수가 첫 번째 장소에서 자물쇠를 든 사람이 이제는 그것을 풀 수 있다는 것을 의미합니다. 이 솔루션의 유일한 불편 함은 잠금을 보유하고있는 스레드가 모든 사용자가 잠금을 해제 할 수있을 때까지 살아 있어야한다는 것입니다.

관련 문제