펜스를 사용하여 C11에서 비 원자 연산의 동작을 판단 할 수있는 방법이 있습니까? 특히, 특정 필드가 int
일 필요가있는 상황에서 코드를 읽거나 쓰거나 시스템 호출 인수로 전달할 수있는 이전 인터페이스와의 호환성을 위해 코드를 안전하게 만들고 싶습니다. atomic_int
이 int
과 같은 크기 일 필요는 없으므로 atomic_int
을 사용할 수 없습니다.C11에서 원자가가 아닌 울타리
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>
int ready; /* purposely NOT _Atomic */
int value;
void
p1()
{
value = 1;
atomic_thread_fence(memory_order_release);
ready = 1;
}
void
p2(void *_ignored)
{
while (!ready)
;
atomic_thread_fence(memory_order_acquire);
printf("%d\n", value);
}
int
main()
{
thrd_t t;
thrd_create(&t, p2, NULL);
p1();
thrd_join(&t, NULL);
}
내 특정 질문은 위의 코드를 수정하는 것이 가능 여부 :
여기에 불행히도 때문에 ready
의 데이터 인종, 섹션 5.1.2.4 문단 25에 따라 정의되지 않은 동작을 생산하는 최소한의 작업 예제 ready
을 _Atomic
으로 변경하지 않고 인쇄 1
을 보장합니다. (ready
을 volatile
으로 만들 수 있지만이 방법이 도움이된다는 제안이 표시되지 않습니다.)
관련 코드는 위의 코드를 작성하는 것이 안전한지 여부입니다. 캐시 일관성이 있습니까? C11 프로그램에 소위 양성 종족이 포함되어있을 때 manythings으로 이동한다는 것을 알고 있습니다. 따라서 데이터 레이스와 정의되지 않은 일반적인 경고가 아닌 위의 코드에서 가능한 컴파일러와 아키텍처의 세부 사항을 찾고 있습니다. 행동.
C11의 모든 동기화 작업은 원자 단위 (또는 'mtx_t')에서만 작동합니다. 원자가 없으면 결코 작동하지 않습니다. 일단 당신이 상태를 제어하는 원자를 가지면, 비 원자력 (non-atomci) 객체들에 대한 효과에 대해서조차도, 쓰레드에서 보이는 효과가 나타나기 전에 일어나는 관계로 논쟁 할 수있다. **하지만 ** 당신의 것들을 오래된 인터페이스와 "호환"하게 만드는 것은 C11의 원자 단위로는 절망적입니다. 그들은 이것을 위해 만들어지지 않았습니다. 시스템의 상태에 따라 이러한 오래된 인터페이스가 비 원자 적으로 작동하도록하여 사용자가 생각할 수있는 일관성의 증거로 구멍을 뚫습니다. –
@JensGustedt 그러나, 제 질문은 울타리에 관한 것이지, 분광에 관한 것이 아닙니다. 울타리는 비 원자 메모리 연산의 순서를 제한합니다. 이 특정 예에서, 릴리스 펜스는 획득 펜스보다 먼저 발생하기 때문에 '준비'상태에서만'value'에 경쟁이 없습니다. 그래서 아마도 두 가지 경우 모두에서'memory_order_acq_rel'을 사용하겠습니까? – user3188445
아니,이 문제에 대해 당신이 잘못 생각한 것 같습니다. 다른 스레드의 두 울타리는 원자 단위로만 동기화됩니다. 한 울타리가 다른 것에 의해 감지되는 원자 물체를 수정하지 않고 다른 울타리보다 앞서 일어난다 고 주장 할 수있는 다른 방법은 없다. –