C에서 "i+=1;" 원자?
C 는i+=1;원자력?
C 표준은 원자인지 아닌지를 정의하지 않습니다.
실제로, 주어진 연산이 원자적이면 실패하는 코드를 절대 쓰지 않지만, 그렇지 않으면 실패하는 코드를 쓸 수도 있습니다.그러니 그렇지 않다고 가정해 보세요.
아니요.
C 은 C 에서 atomic 으로입니다.sig_atomic_t됨, <signal.h>.
(C99장, 7.14장 신호 취급)
C로 정의, 아니요.실제로, 아마도.조립할 때 써요.
표준은 보장하지 않습니다.
따라서 휴대용 프로그램은 이러한 가정을 할 수 없습니다."원자가 되어야 한다"는 뜻인지, 아니면 "내 C 코드에서 원자가 되는 일이 발생한다"는 뜻인지는 분명하지 않으며, 두 번째 질문에 대한 답은 그것이 많은 것에 달려 있다는 것입니다.
모든 시스템에 증분 메모리 op가 있는 것도 아닙니다.일부는 값을 로드하고 저장해야 작동하기 때문에 "절대"라는 답이 없습니다.
증분 메모리 op가 있는 시스템에서는 컴파일러가 로드, 증분 및 저장 시퀀스를 출력하거나 다른 비원자 명령어를 사용하지 않을 것이라는 보장이 없습니다.
메모리 증가 작업이 있는 시스템에서는 다른 CPU 장치에 대해 원자성 메모리일 수도 있고 그렇지 않을 수도 있습니다.
원자 증분 메모리 op가 있는 시스템에서는 아키텍처의 일부로 지정되지 않고 특정 버전의 CPU 칩의 속성이거나 특정 코어 로직 또는 마더보드 설계로 지정될 수도 있습니다.
"어떻게 해야 원자적으로 이것을 할 수 있을까"에 관해서는, 일반적으로 협상된 상호 배제에 의존하기 보다는, 이것을 신속하게 할 수 있는 방법이 있습니다.때때로 이것은 반복 가능한 코드 시퀀스를 특별하게 충돌 감지하는 것을 포함합니다.조립 언어 모듈에서 구현하는 것이 가장 좋습니다. 어차피 대상에 따라 다르므로 HLL에 휴대성의 이점이 없기 때문입니다.
마지막으로, (비용이 많이 드는) 협의된 상호 배제를 필요로 하지 않는 원자 연산은 빠르고 따라서 유용하기 때문에, 휴대용 코드에 필요한 어떤 경우에도 시스템은 일반적으로 어셈블리로 작성되는 라이브러리를 가지고 있으며, 이미 유사한 기능을 구현합니다.
식이 atomic인지 아닌지 여부는 컴파일러가 생성하는 시스템 코드와 컴파일러가 실행할 CPU 아키텍처에만 따라 달라집니다.하나의 기계 명령에서 추가를 달성할 수 없는 한, 원자가 아닐 가능성이 높습니다.
Windows(윈도우)를 사용하는 경우 Interlocked(연동)를 사용할 수 있습니다.보장된 원자 증분을 수행하기 위한 증분() API 함수입니다.감소 등에 대해서도 유사한 기능이 있습니다.
제가 C 언어의 원자가 아닐 수도 있지만, 대부분의 플랫폼에서 원자가 된다는 점에 유의해야 합니다.GNUC 라이브러리 문서에는 다음과 같이 명시되어 있습니다.
실제로 int와 다른 정수형은 int보다 길지 않다고 가정할 수 있습니다.포인터 유형이 원자형이라고 가정할 수도 있습니다. 이는 매우 편리합니다.이 두 가지 가정은 GNU C 라이브러리가 지원하는 모든 기계와 우리가 알고 있는 모든 POSIX 시스템에서 모두 사실입니다.
이것은 실제로 당신의 목표와 당신의 uC/프로세서의 니모닉 세트에 달려있습니다.만약 i가 레지스터에 저장된 변수라면 원자를 가질 수 있습니다.
아닙니다.레지스터 중 하나에 i 값이 이미 로드되어 있지 않으면 하나의 어셈블리 명령에서 실행할 수 없습니다.
C/C++ 언어 자체는 원자성이나 원자성의 결여를 주장하지 않습니다.원자의 거동을 보장하기 위해서는 고유한 함수나 라이브러리 함수에 의존해야 합니다.
그냥 뮤텍스나 세마포를 둘러보세요.물론 원자는 아니며 50개 정도의 스레드가 동일한 변수에 접근하여 증가시키는 테스트 프로그램을 만들어 직접 확인할 수 있습니다.
보통은 아니에요.
한다면i이다.volatile, 그러면 그것은 당신의 CPU 아키텍처와 컴파일러에 달려있을 것입니다 - 만일 메인 메모리에서 두 개의 정수를 추가하는 것이 당신의 CPU에서 원자라면, 그 C 문장은 a와 원자일 수 있습니다.volatile int i.
아니요, C 표준은 원자성을 보장하지 않으며, 실제로는 작동이 원자성을 보장하지 않습니다.라이브러리(예: Windows API) 또는 컴파일러 내장 함수(GCC, MSVC)를 사용해야 합니다.
은 됩니다 있습니다.i지역 주민인데요static, 아니면 전역 변수. 만약에.istatic수,요,요i += 1원자가 아닙니다.일.i는 로컬 변수이며, x86 아키텍처 및 다른 아키텍처에서 실행되는 최신 운영 체제에 대한 문은 atomic입니다.@Dan Christoloveanu는 지역 변수 사건에 대해 올바른 방향으로 가고 있었지만, 더 말할 수 있는 것이 있습니다.
(다음 내용에서는 작업 전환으로 스레드화를 완전히 구현한 x86 아키텍처에서 보호 기능을 갖춘 최신 운영 체제를 가정합니다.)
이것이 C 코드인 것을 감안하면, 구문은i += 1은 암시합니다i는 일종의 정수 변수이며, 만약 그것이 지역 변수라면, 그 값은 다음과 같은 레지스터에 저장됩니다.%eax혹은 스택 안에서.쉬운 사건을 먼저 처리하는 것, 만약 가치가 있다면,i예를 들어, 레지스터에 저장되어 있습니다.%eax, 그러면 C 컴파일러는 이 문장을 다음과 같은 것으로 번역할 가능성이 높습니다.
addl $1, %eax
다른 프로세스/thread가 실행 중인 스레드의 것을 수정할 수 없기 때문에 당연히 원자적입니다.%eaxregister, 그리고 스레드 자체는 수정할 수 없습니다.%eax이 지침이 완료될 때까지 다시 확인합니다.
의 가치가 있다면i스택에 저장되며, 이는 메모리 페치, 증분 및 커밋이 있음을 의미합니다.다음과 같은 경우:
movl -16(%esp), %eax
addl $1, %eax
movl %eax, -16(%esp) # this is the commit. It may actually come later if `i += 1` is part of a series of calculations involving `i`.
일반적으로 이 일련의 작업은 원자력이 아닙니다.그러나 현대의 운영 체제에서는 프로세스/스레드가 다른 스레드의 스택을 수정할 수 없어야 하므로 이러한 작업은 다른 프로세스가 간섭하지 않고 완료됩니다.따라서 그 진술은i += 1이 경우에도 원자력입니다.
언급URL : https://stackoverflow.com/questions/1790204/in-c-is-i-1-atomic
'programing' 카테고리의 다른 글
| 하이버네이트가 MySQL의 "ON DUFFICED KEY UPDATE" 구문과 함께 작동할 수 있습니까? (0) | 2023.10.01 |
|---|---|
| 포인터가 유효한지 확인하는 방법은? (0) | 2023.10.01 |
| 컨텍스트 기반 DB 감사 구현 방법은? (0) | 2023.10.01 |
| GCC는 정적 분기 예측을 위한 차선의 코드를 생성합니까? (0) | 2023.10.01 |
| MySQL LOAD DATA INFILE은 이후에 메모리를 지우지 않습니다. (0) | 2023.10.01 |