enable = true
만 설정할 필요가있는 경우 릴리스/획득 주문 번호 stdatomic.h
을 입력하면 정확하게 원하는 내용을 얻을 수 있습니다. (x86에서 asm, normal stores/loads는 release/acquire 의미론을 가지고 있기 때문에 컴파일 시간 재 배열을 막는 것만으로도 충분합니다. 그러나 올바른 방법은 가 아니라 atomic
입니다.)
그러나 독자가 수정하는 동안 enable = false
을 다시 "잠금"하도록 설정하려면보다 복잡한 업데이트 패턴이 필요합니다. atomics로 수동으로 뮤텍스를 다시 만들거나 (나쁜 생각, 표준 라이브러리 뮤텍스를 사용하는 것), 또는 라이터가 업데이트 중간에 없을 때 여러 독자가 대기하지 않는 읽기 전용 액세스를 허용하는 작업을 수행하십시오.
어느 RCU a 또는 seqlock 여기 좋은 수 있습니다.
seqlock의 경우 enable = true/false 플래그 대신 일련 번호가 있습니다. 독자는 다른 구성원을 읽은 후 순서 번호를 확인한 후 "찢어진"쓰기를 감지 할 수 있습니다. (그러나 모든 구성원은 적어도 mo_relaxed
을 사용하여 atomic
이어야하며, 그렇지 않으면 값을 무시한 경우에도 데이터를 C에서 읽지 않고 정의되지 않은 동작을합니다. 또한 카운터를 검사하는로드에 대해 충분한 순서가 필요합니다. 아마 첫 번째 인수를 획득 한 다음 shared_struct->b
로드에서 획득하여 시퀀스 번호의 두 번째로드가 그 다음에 정렬되도록하십시오. (acquire
은 단방향 장벽 일뿐입니다. 느슨한로드 후에 획득로드로 인해 당신이 필요로하는 것입니다.)
RCU는 독자가 항상 완전히 대기 상태가되지 않도록하며, 현재 유효한 구조체에 대한 포인터를 참조 해제합니다. 포인터를 원자 적으로 바꾸는 것만 큼 간단합니다. 오래된 구조체를 재활용하면 복잡해질 수 있습니다. 모든 리더 스레드가 mem 블록을 읽었는지 확인해야합니다. 당신이 그것을 재사용하기 전에 ory.
은 단순히 작가를 수정하는 동안 다른 회원들에 대해 일관성없는/부분적으로 업데이트 된 값을보고 다음 enable == true
을 보는 독자를 중지하지 않는 다른 구조체 멤버를 변경하고 이전 enable = false
설정. 그렇게 할 필요는 없지만 다른 스레드가 액세스 할 수 있도록 새 오브젝트를 릴리스하는 경우에만 설명하는 시퀀스는 atomic_store_explicit(&foo->enable, true, memory_order_release)
으로 문제가 없습니다.
* 전혀 변하지 않았습니다. 휘발성이 있습니다. 원자 플래그가 있으면 C11' ' –
을 사용해야합니다. 휘발성 액세스가 재정렬되지 않는 "부산물"입니다. – filo
@AnttiHaapala 원자 접근은 명령 순서 재 지정과 무슨 관련이 있습니까? – Lundin