C에서 포인터를 변경하는 것은 원자 작용으로 간주됩니까?
캐시 타입 메모리를 참조로 읽어주는 멀티 스레드 프로그램이 있는 경우.예상치 못한 값을 읽는 다른 스레드를 위험에 빠뜨리지 않고 메인 스레드로 포인터를 변경할 수 있습니까?
제가 볼 때, 변경 사항이 원자적인 경우 다른 스레드는 이전 값 또는 새로운 값을 읽습니다. 절대 랜덤 메모리(또는 널 포인터)는 읽지 않습니까?
어쨌든 동기화 방법을 사용해야 한다는 것은 알고 있지만 여전히 궁금합니다.
포인터 변경이 원자성입니까?
업데이트: 제 플랫폼은 64비트 Linux(2.6.29)이지만 크로스 플랫폼 답변도 원합니다. :)
다른 사람들이 언급한 것처럼 C 언어에는 이를 보장하는 것이 없으며, 당신의 플랫폼에 의존합니다.
대부분의 현대 데스크톱 플랫폼에서 단어 크기의 정렬된 위치에 대한 읽기/쓰기는 원자 단위입니다.그러나 프로세서와 컴파일러의 읽기 및 쓰기 순서 변경으로 인해 문제가 해결되지는 않습니다.
예를 들어, 다음 코드가 끊겼습니다.
스레드 A:
DoWork();
workDone = 1;
스레드 B:
while(workDone != 0);
ReceiveResultsOfWork();
에게 을 썼지만workDone
atomic,가 atomic이라는 가 보장하지 .서가에해지다은다지해s서에가y은ceee,snworkDone
를 통해 에 다른 가 볼 수 .DoWork()
눈에 띕니다.컴파일러는 또한 자유롭게 쓰기 순서를 바꿀 수 있습니다.workDone
에게 전화하기 전에DoWork()
모두, . . ReceiveResultsOfWork()
불완전한 데이터에 대한 작업을 시작할 수도 있습니다.
플랫폼에 따라 메모리 펜스 등을 삽입하여 주문이 제대로 이루어지는지 확인해야 할 수도 있습니다.이것은 바로 잡기가 매우 어려울 수 있습니다.
아니면 그냥 자물쇠를 사용해요.훨씬 단순하고, 정확한 것으로 확인하기가 훨씬 쉬우며, 대부분의 경우 성능이 충분히 뛰어납니다.
C 언어는 어떤 작업이 원자적인지에 대해 아무것도 언급하지 않습니다.저는 8비트 버스와 16비트 포인터로 마이크로컨트롤러 작업을 해왔습니다. 이러한 시스템에 대한 포인터 작업은 원자가 아닐 가능성이 있습니다.인텔 386s(일부는 16비트 버스)도 비슷한 우려를 제기했던 것으로 기억합니다.마찬가지로 64비트 CPU를 사용하지만 32비트 데이터 버스를 사용하는 시스템도 원자가 아닌 포인터 작동에 대해 비슷한 우려를 가질 수 있습니다.(그런 시스템이 실제로 존재하는지 확인하지 않았습니다.)
편집: 마이클의 대답은 읽을 만한 가치가 있습니다.버스 크기와 포인터 크기가 원자성과 관련된 유일한 고려 사항은 아닙니다. 그것은 단순히 저에게 처음으로 떠오른 반례였습니다.
플랫폼에 대해서는 언급하지 않으셨군요.그래서 조금 더 정확한 질문은
포인터 변경은 원자성으로 보장됩니까?
이 동작에서 C/C++ 구현이 다를 수 있으므로 구별이 필요합니다.특정 플랫폼이 원자 할당을 보장하면서도 표준 내에 있는 것은 가능합니다.
이것이 C/C++에서 전반적으로 보장되는지 여부에 대해서는 No라고 답합니다.C 표준에는 그러한 보장이 없습니다.포인터 할당을 보장하는 유일한 방법은 할당의 원자성을 보장하기 위해 플랫폼 고유 메커니즘을 사용하는 것입니다.예를 들어, Win32의 Interlocked 메서드는 이러한 보증을 제공합니다.
어느 플랫폼에서 작업하고 계십니까?
cop-out 답변은 C 사양은 포인터 할당이 원자가 될 필요가 없으므로 원자가 될 것이라고 기대할 수 없다는 것입니다.
실제적인 대답은 아마도 당신의 플랫폼, 컴파일러, 그리고 당신이 프로그램을 작성한 날 별들의 정렬에 달려있을 것입니다.
'normal' 포인터 수정은 원자성이 보장되지 않습니다.
C 표준이 아닌 'Compare and Swap'(CAS) 및 기타 원자 연산을 확인하지만 대부분의 컴파일러는 프로세서 프리미티브에 일부 접근할 수 있습니다.GNU gcc의 경우, 몇 가지 내장 함수가 있습니다.
표준에서 보장하는 것은 sig_atomic_t 타입뿐입니다.
다른 답변에서 보셨듯이, 일반 x86 아키텍처를 대상으로 할 때는 문제가 없을 가능성이 높지만, 보다 "전문성"이 높은 하드웨어를 사용하면 매우 위험합니다.
정말 알고 싶다면 (sig_atomic_t)의 크기와 (int*)의 크기를 비교하여 목표 시스템이 무엇인지 확인할 수 있습니다.
상당히 복잡한 질문인 것으로 드러났습니다.저도 비슷한 질문을 하고 제가 지목받은 내용을 다 읽어봤습니다.저는 캐싱이 현대 아키텍처에서 어떻게 작동하는지에 대해 많은 것을 배웠지만 확실한 것은 찾지 못했습니다.다른 사람들이 말했듯이 버스 폭이 포인터 비트 폭보다 작으면 큰일 날 수 있습니다.특히 데이터가 캐시 라인 경계에 해당하는 경우.
신중한 건축은 자물쇠를 사용할 것입니다.
언급URL : https://stackoverflow.com/questions/879077/is-changing-a-pointer-considered-an-atomic-action-in-c
'itsource' 카테고리의 다른 글
Composer 및 autoload.php를 사용하여 PHPUnit에서 수업 자동 로딩 (0) | 2023.09.14 |
---|---|
Rails 3은 연결 카운트 조건에 따라 쿼리 (0) | 2023.09.14 |
jQuery : blur() 이벤트 전 fire click() 이벤트 (0) | 2023.09.14 |
jquery - 동적으로 만든 단추에 대해 작동하지 않는 이벤트 클릭 (0) | 2023.09.14 |
하나의 스키마를 다른 새 스키마(Oracle)로 가져오기 (0) | 2023.09.14 |