0

연습의 설명 :
너는 튀김의 부분을 요구할 수있는 N 점이있는이 대중 음식점이있다. 각 포인트는 M 부분을가집니다. 튀김이 1 개 있습니다. 주문 지점에 2 개의 부분이 있으면 cheff에게 리필이 필요하다는 경고를 보냅니다. cheff는 FIFO 순서대로 부분을 전달합니다. wait()/signal() 블록에서 뮤텍스 획득이 어떻게됩니까?

 init { 
    Semafoor[] mutex; 
    Condition[] cond_point = new Condition[N]; 
    int[] portions = new int[N]; 
    ArrayList<int> waitline = new ArrayList<int>(); 

    for(int i = 0; i < N; i++) { 
     mutex[i] = new Semafoor(1); 
     portions[i] = M; 
    } 
} 

point(int n) { 
    while(1) { 
     mutex[n].acquire(); 
     if(portions[n] == 0) { 
      cond_point[n].wait(mutex[n]); 
     } 
     else if(portios[n] == 2) { 
      waitline.add(n); 
     } 
     portions[n]--; 
     mutex[n].release(); 
    } 
} 

frycheff() { 
    int n; 
    while(1) { 
     if(!waitline.empty()) { 
      n = waitline.remove(0); 
      mutex[n].acquire(); 
      portions[n] += M; 
      cond_point[n].signal(); 
      mutex[n].release(); 
     } 
    } 
} 

그래서 우리가 때 wait() 문 블록 point(int n) 신호를 발생하는 궁금해 : 우리는이 의사 코드를했다. 다큐멘터리에서 뮤텍스를 원자 적 방식으로 공개 했으므로 간섭이 없다고 말합니다. 하지만 다른 코드 줄은 어떨까요? ( point(int n) 함수에서)? portions[n] 등 - 회선이 삭제 되었습니까? signal() 문은 point(int n) 기능으로 리콜되지만 리셋 방식으로 기능이 새로운 기능으로 실행됩니까? 미리 감사드립니다.

+0

왜 부분 [n] -;이 (가) 삭제 되었습니까? 나는 당신이 기다림/신호가 점프 지시와 같은 것이라고 생각하는 느낌을 가지고있다. 그러나 그것은 사실이 아니다. – 1000ml

+0

뮤텍스가 출시 되었기 때문에 – JasperHofman

+0

아아, 나는 본다. - 뮤텍스가 기다리기 전에 재실행된다. – 1000ml

답변

1

자세한 내용은 wait()의 설명서 페이지를 참조하십시오. 구체적으로 pthread 구현에 대해 말하지만 이것은 일반적으로 모든 구현에 적용됩니다.
https://linux.die.net/man/3/pthread_cond_wait

가장 중요한 부분이있다 :


는 pthread_cond_wait() 함수는 조건 변수

wait() 차단 호출 인에 차단한다. 쓰레드는 스케줄러에 의해 잠자기 상태가됩니다. 신호가 수신되면 wait()이 반환됩니다. 점프가 없습니다. 실행은 wait() 바로 다음에 계속됩니다.

주 :이 가능의 때문에 가짜를 깨우는 좋은 이유없이 wait() 돌아갑니다. 따라서 조건이 실제로 충족되는지 확인해야합니다. 루프에서 wait() 전화 :

// Condition: portions[n] > 0 
while(portions[n] == 0) 
    cond_point[n].wait(mutex[n]); 

이 그들은 호출 스레드 또는 정의되지 않은 동작이 결과에 의해 잠겨 뮤텍스를 호출해야한다.

wait()이 호출 될 때 이미 뮤텍스를 잠글 필요가 있습니다.

성공적인 복귀시

, 뮤텍스가 잠긴하며 호출 스레드가 소유해야한다.

wait()이 반환하면 잠금이 다시 설정됩니다. 당신이 보았 듯이 다른 것은 의미가 없으며 혼란스러운 상황으로 이어질 것입니다.

--- point ------------------------- frycheff ------------------- 
mutex[n].acquire();     Serving other Points 
else if(portios[n] == 2)   Serving other Points 
waitline.add(n);     Serving other Points 
portions[n]--;      Serving other Points 
mutex[n].release();     Serving other Points 
... 
mutex[n].acquire(); (BLOCKS)  if(!waitline.empty()) 
mutex[n].acquire();     n = waitline.remove(0); 
if(portions[n] == 0)    mutex[n].acquire(); (BLOCKS) 
cond_point[n].wait(mutex[n]);  mutex[n].acquire(); 
Sleeping       portions[n] += M; 
Sleeping       cond_point[n].signal(); 
wait() reaquires mutex[n]   mutex[n].release(); 
portions[n]--;      if(!waitline.empty()) 
mutex[n].release();     if(!waitline.empty()) 

을 Btw는 :


그래서 이런 일 (수) 할 것입니다 당신은 아마 ArrayList에 대한 쓰기 작업이 threadsave되지 않기 때문에 if(!waitline.empty())n = waitline.remove(0);에 frycheff의 전화를 동기화 할 다른 뮤텍스를 사용해야합니다 .

+0

대단히 감사합니다! – JasperHofman