2015-01-05 2 views
0

아래 코드는 중요한 섹션 문제를 해결하기 위해 작성되었습니다. 중요 섹션에서 공통 데이터 구조를 수정하는 N 개의 프로세스가 있다는 것을 감안할 때. 여기waiting [i] = false를 건너 뛰면 어떻게됩니까? 다음 코드 조각에서?

boolean waiting[n]; 
boolean lock; 

하드웨어 지원에 의한 실행에 원자 추정되는 검사와 지정() 함수이다 :

이 사용 된 데이터 구조이다.

boolean TestAndSet(boolean *target) 
{ 
    boolean rv = *target; 
    *target = TRUE; 
    return rv; 
} 

// 다음 코드는 상호 배제를 보장

do { 
    waiting[i] = TRUE; 
    key = TRUE; 

    while (waiting[i] && key) 
     key = TestAndSet(&lock); 

    waiting[i] = FALSE; //what if I skip this?? 

    // critical section 

    j = (i + 1) % n ; 
    while((j != i) && ! waiting[j]) 
    { 
     j = (j + 1) % n ; 
    } 
    if (j == i) 
     lock = FALSE; 
    else 
     waiting[j] = FALSE; 

    //remainder section 

    }while (TRUE); 

답변

2

첫 번째 줄 이후 정말로 들여 쓰기가 필요합니다.

"임계 영역"아래의 항목은 액세스를 기다리는 다음 작업의 잠금을 해제하거나 아무도 기다리지 않으면 잠금을 해제합니다.

대기 플래그를 지우지 않으면 이미 잠겨 있던 다른 작업 (아마도 보호 메모리에 대한 액세스와 관련하여 동일한 코드가 실행 중일 것임)이 아직 대기 중이며 대기 플래그를 지울 것으로 생각됩니다 (루프에 앉아 있다고 가정하고, 대기 플래그가 참인 유일한 위치 인 TestAndSet을 확인하십시오). 잠금 플래그를 설정하면 잠금이 전달되기 때문에 잠금 플래그가 설정된 상태로 유지됩니다. 그러나 값을 false로 설정하지 않고 코드가 실제로 그 지점에서 계속 움직 였다면 대기 플래그를 True로 설정하지 않고 TestAndSet으로 돌아갈 수 없으며 잠금도 true로 유지되므로이 작업을 수행 할 수 없습니다 실행 중이며 다른 작업이 실행 중이 지 않습니다. 줄의 다음 작업에 계속 진행 (또는 잠금이 false로 설정되지 않음)이 주어지지 않았기 때문에 전체 시스템이 거칠어지기 때문입니다.

+0

또한 여기에 메모리 장벽이있을 수있는 곳은'TestAndSet'의 구현이 사용되는 범위 내이므로 엄격한 캐시보다 적은 다중 프로세서 다중 캐시 시스템에서 많은 재미를 보일 수 있습니다 coherency constraints ... 특히'waiting [J] = FALSE'는 (비교적) 다른 CPU가 알아 차릴 수있는 꽤 많은 시간을 필요로합니다 ... 아니면 적어도 캐시 라인 바운싱과 관련된 성능 열화를 일으킬 것입니다 ... – twalberg

+0

@Nerf 우리가 2 개의 프로세스 A와 B를 가지고 있다고 가정합시다. A 잠금을 획득하고 임계 영역을 완료 한 다음 대기 [A]를 거짓으로 설정하지 않았습니다. 이제 B를 실행합니다. 잠금 해제 됨이 표시되면 잠금을 획득하고 핵심 섹션으로 실행됩니다. 이제 critical 섹션 이후의 코드는 프로세스 B에서 실행됩니다. 인덱스가 A에 도달하면 중지됩니다. 이제 Waiting [A] = false로 설정됩니다. 2 가능성이 존재합니다 1) A가 while 루프에서 잠금 대기 중입니다. 이 경우에 대기는 A.에 대한 대기가됩니다. 2) 또는 A가 나머지 섹션을 실행 중입니다.이 경우 대기 [A]를 거짓으로 설정하면 영향이 없습니다. –

+0

가능성 1)은 괜찮지 만 2)에 영향을 미칩니다. 첫 번째로 합법적으로 대기중인 프로세스 C가있는 경우 프로세스 C가 건너 뛸 수 있습니다. C가 없더라도 A는 Waiting [A] = true로 설정하지 않고 while 루프로 돌아갈 수 없습니다. lock이 false로 설정되지 않았으므로 이제 A는 TestAndSet 루프에서 영원히 기다립니다. 다른 모든 사람들에게도 마찬가지입니다. –

0

당신은 여전히 ​​락의 취득을 대기하는 것을 의미하는 것 '... = FALSE'라인을 건너 뛸 경우 (임계 영역) 첫 번째 while 루프 (특정 i)에서 두 번째 while 루프에서 "라운드 로빈 (round robin)"액세스의 중요 영역을 중단합니다.

+0

여전히 얻을 수 없습니다. 예가 매우 도움이 될 것입니다. –

+0

두 번째 while 루프는 다시 대기 잠금을 사용하지 않고 대기 플래그를 설정 한 모든 사람에게 순환 섹션 (순환 로빈)으로 중요한 섹션보다 TRUE 소유권을 부여합니다. 아무도 기다리지 않으면 잠금 장치가 해제됩니다. 내가 너에게 간단한 exmple을 줄 수 있을지 확신하지 못한다. – lonewasp

+0

모든 n 개의 작업이 동일한 코드를 실행하고 있음을 기억하십시오. 따라서 다른 작업에서는이 작업이 실제로는 그렇지 않을 때까지 기다리는 것으로 보입니다. 자물쇠를 풀고 누가 실제로 문제를 일으키는 지 결정합니다. –

0

해당 줄을 제거하면 모든 것이 손상 될 수 있습니다. 바로 위의 두 줄은 waiting[i]이 거짓이되거나 key이 거짓 (또는 둘 다 "동시에")이되는 두 조건 중 하나에서 종료 될 수있는 while 루프입니다. key이 거짓이어서 루프가 종료되면 waiting[i]이 여전히 사실 일 수 있으므로 잠금을 유지하고 동시에 잠금을 기다리고있는 것으로 생각되는 상황이 발생하여 후속 while의 전제 조건을 위반했을 가능성이 높습니다 루프 ...

+0

예 대기중인 단계를 건너 뛰면 이론적으로 윤리적이지 않을 것입니다. [i] == true는 i 번째 프로세스가 중요 섹션에 액세스하려고 함을 의미하지만 실용적인 예를 생각할 수 있으면 되돌릴 수 있음을 의미합니다. –

+0

메모리 보호를 깨뜨리는 실질적인 예는 무엇입니까? –

+0

특정 "i"에 대해 대기 [i]에 대한 두 개의 첫 번째 할당이 제거되면 "대기열에 한 번만 대기하고 다시 대기"와 같은 항목이있을 수 있습니다. – lonewasp

0

나는 그것을 얻었습니다. 전체 혼동은 전체 코드를 감싸는 do() 루프에 의해 만들어집니다. 이러한 프로세스를 나타내는 몇 가지 기능을 같이한다면

function(int i) 
{ 
    waiting[i] = TRUE; 
    key = TRUE; 

    while (waiting[i] && key) 
    key = TestAndSet(&lock); 

    waiting[i] = FALSE; //what if I skip this?? 

    // critical section 

    j = (i + 1) % n ; 

    while((j != i) && ! waiting[j]) 
    { 
    j = (j + 1) % n ; 
    } 

    if (j == i) 
    lock = FALSE; 
    else 
    waiting[j] = FALSE; 

    //remainder section 
} 

함수는 I = 3이라고 말할 수 등이 대신에, 동안() 일을 (예를 들어 프로세스 I3. N에 대한 = 5). 그리고이 프로세스는 다시 실행되지 않습니다. wait [3] = false로 설정하면 교착 상태가됩니다. 프로세스 i4는 프로세스 i3이 실행되기를 원한다고 생각할 수 있으므로 대기 [3] = false로 설정하고 잠금을 해제하지 않음으로써 끝날 것입니다.