Обработка исключений в сложенных семафорах - PullRequest
0 голосов
/ 12 апреля 2020

У меня общий вопрос, когда несколько семафоров накладываются друг на друга - как правильно обрабатывать исключения для таких ситуаций в контексте блоков try и finally.

В приведенном ниже коде есть два семафора sP и sC, которые используются для указания полноты и пустоты стека соответственно. lock служит мьютексом для критической секции.

Как правильно обрабатывать исключения с семафорами sP и sC, сложенными с семафором lock. Кажется, что исключения в блоках try должны обрабатываться более осторожно для семафоров sP и sC, и если это так, каков будет чистый способ обработки их правильного освобождения? Нужно ли мне отдельное вложение try / finally, и если да, то как учесть сбои во внутреннем блоке try.

Хотя ниже приведено в java, это вопрос общего параллелизма, т.е. не спецификация языка c.

import java.util.concurrent.Semaphore;

class Buffer {
  Semaphore sC;
  Semaphore sP;
  Semaphore lock;
  int capacity;
  int count;
  int[] s; // FIFO stack

  public int get() throws InterruptedException {
    int tmp = -1;
    sC.acquire();
    lock.acquire();
    try { 
      if(count>0) {
        count-=1;
        tmp = s[count];
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      System.out.println("Get: "+tmp);
      lock.release();
      sP.release();
    } 
    return tmp;
  }

  public void put(int i) throws InterruptedException {
    sP.acquire(); 
    lock.acquire();
    try {
      if(count<capacity){
        s[count]=i;
        count+=1;
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      System.out.println("Put: "+i);
      lock.release();
      sC.release();
    }
  }

  Buffer(int numItems) {
    capacity = numItems;
    sP = new Semaphore(numItems);
    sC = new Semaphore(0);
    lock = new Semaphore(1);
    s = new int[numItems];
  }
}

Редактировать После Йоханнес Кун подсказка:


  public int get() throws InterruptedException {
    int tmp = -1;
    sC.acquire();
    try {
      lock.acquire();
      try { 
        if(count>0) {
          count-=1;
          tmp = s[count];
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        System.out.println("Get: "+tmp);
        lock.release();
      }
    } catch (Exception e) {
      sC.release();
    } finally {
      sP.release();
    } 
    return tmp;
  }

  public void put(int i) throws InterruptedException {
    sP.acquire();
    try {  
      lock.acquire();
      try {
        if(count<capacity){
          s[count]=i;
          count+=1;
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        lock.release();
      }
    } catch (Exception e) {
      sP.release();
    } finally {
      sC.release();
    }
  }

Редактировать 2: После еще одного из Йоханнес Кун подсказка: (изменено, чтобы отразить то же вложение, что и в put())

  public int get() throws InterruptedException {
    int tmp = -1;
    boolean lockException = false;
    sC.acquire();
    try {
      lock.acquire();
      try { 
        if(count>0) {
          count-=1;
          tmp = s[count];
        }
        return tmp;
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        System.out.println("Get: "+tmp);
        lock.release();
      }
    } catch (Exception e) {
        sC.release();
        lockException = true;
    } finally {
      if (!lockException) {
        sP.release();
      }
    }
    return -1;
  }

  public void put(int i) throws InterruptedException {
    boolean lockException = false; 
    sP.acquire();
    try {
      lock.acquire();
      try {
        if(count<capacity){
          s[count]=i;
          count+=1;
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        System.out.println("Put: "+i);
        lock.release();
      }
    } catch (Exception e) {
      sP.release();
      lockException = true;
    } finally {
      if (!lockException) {
        sC.release();
      }
    }
  }
}
...