홈>
이 코드는 Pintos 소스에서 온 것입니다.
https : //www.cs.usfca. edu/~ benson/cs326/pintos/pintos/src/threads/synch.c
void
sema_down (struct semaphore *sema)
{
enum intr_level old_level;
ASSERT (sema != NULL);
ASSERT (!intr_context ());
old_level = intr_disable ();
while (sema->value == 0)
{
list_push_back (&sema->waiters, &thread_current ()->elem);
thread_block ();
}
sema->value--;
intr_set_level (old_level);
}
세마포어를 복용하는 사실은
sema->value--;
입니다.
. 작동하는 경우 원 자성 작업이어야합니다.
그것이 실제로 원자 작동이라는 것을 어떻게 알 수 있습니까? 현대 CPU는 정렬 된 메모리 작업 (단어/더블 워드/쿼드 워드의 경우)이 원자적임을 보장합니다. 그러나, 나는 그것이 왜 그것이 원자 적인지 확신하지 못한다.
-
답변 # 1
관련 질문
- c++ Multithreading - c ++ 멀티 스레딩 - 공유 변수에 대한 쓰기가 처리되는 방법
- concurrency - 단일 코어로 멀티 스레딩 이점 없음
- x86 - x64에서 분할이 완전히 사용되지 않습니까?
- multithreading - 커널 공간에서 구현 된 스레드가 느린 이유는 무엇입니까?
- multithreading - Java에서는 생성자의 최종 필드 할당에 어떤 작업이 관련됩니까?
- multithreading - Anderson의 운영 체제 원칙 및 실습에서 스핀 록을 사용하여 잠금 구현
- multithreading - 사용자 레벨 스레드를 커널에 맵핑
- multithreading - 사용자 프로세스에서 시스템 호출을 처리하기위한 별도의 커널 레벨 스레드가 있습니까?
TL : DR : DMA를 사용하여 메모리를 관찰하는 시스템 장치를 계산하지 않는 한 UP 시스템에서 인터럽트가 비활성화 된 상태라면 아무 문제가 없습니다
.intr_disable ();
참고 /intr_set_level (old_level);
작업 주위에.멀티 스레드 옵저버의 경우 읽기-수정-쓰기 작업이 아닌또는개별로드에만 적용됩니다.
<시간>원자가되기 위해서는 관심있는 관찰자가 무엇을 고려해야하는지고려해야합니다. 중요한 것은 작업이 부분적으로 발생한 것으로 아무것도관찰할 수 없다는 것입니다. 이를 달성하는 가장 간단한 방법은 작업이 물리적/전기적으로 순간적으로 이루어지고 모든 비트에 동시에 영향을주는 것입니다 (예 : 병렬 버스의로드 또는 저장은 클럭 사이클의 경계에서 시작되지 않은 상태에서 완료된 상태로 진행됨). 그것은 병렬 버스의 너비까지 "무료"원자입니다). 읽기-수정-쓰기는 불가능합니다. 여기서 관찰자가 부하와 상점을 보지 못하게하는 것이 최선입니다.
x86의 Atomicity에 대한 나의 대답은 원 자성이라는 것이 무엇을 의미하는지에 대해 같은 방식으로 다른 방식으로 설명했습니다.
<시간>유니 프로세서 (UP) 시스템에서유일한 비동기 관찰자는 다른 시스템 장치 (예 : DMA) 및 인터럽트 처리기입니다. CPU가 아닌 관찰자가 세마포어에 쓰지 못하게 할 수 있다면, 우리가 관심을 갖는 인터럽트와 관련하여 원자 성일뿐입니다.
이 코드는 손쉬운 방법으로 인터럽트를 비활성화합니다. 그럴 필요는 없습니다 (적어도 우리가 asm으로 쓰는 경우는 아닙니다).인터럽트는 명령 중간에 두 명령 사이에서 처리되지 않습니다. 기계의 구조적 상태는 메모리 감소를 포함하거나 포함하지 않습니다.
달렸거나 그렇지 않았다. 우리는 실제로dec [mem]
가 필요하지 않습니다 이것을 위해.BTW, 이것이
<시간>lock dec [mem]
의 유스 케이스입니다.cmpxchg
없이 접두사. 난 왜 그들이 왜 그냥lock
을하지 않았는지 궁금lock
에 암시 적 UP 시스템은 종종cmpxchg
가 필요하지 않기 때문입니다. 접두사.컴파일러가
C11/C ++ 11은 시그널 핸들러/인터럽트와 관련하여 원 자성을 요청하는 방법을 제공하지는 않지만 다른 스레드는 제공하지 않는다고 생각합니다. 그들은lock
를 방출하도록하는 확실한 방법은 없습니다 이와 같은 대신에 :mov eax, [value] ;; interrupt here = bad dec eax ;; interrupt here = bad mov [value], eax
를 제공합니다 컴파일러 장벽으로, x86에서atomic_signal_fence
를 피할 수있는 유형을 기억하지 못합니다. 여전히 원자 유형의 다른 의미론을 가지고 있지만 접두사.C11/C ++ 11
lock
이 아이디어를 염두에두고 있지만 RMW가 아닌 별도의로드/스토어에만 원 자성을 제공합니다.volatile sig_atomic_t
의 typedef입니다. x86 Linux에서. 표준의 인용문은 해당 질문을 참조하십시오.int