Interlocked의 과부하가 없는 이유는 무엇입니까?Double을 매개 변수로 허용하는 추가?
스레딩의 원자성을 충분히 높이 평가합니다.인터락된 클래스는 제공합니다. 하지만 왜 추가 기능이 정수용과 롱용의 두 가지 오버로드만 제공하는지 이해할 수 없습니다.그 문제에 대해 Double 또는 다른 숫자 유형이 아닌 이유는 무엇입니까?
분명히, 이중을 변경하기 위한 의도된 방법은 비교입니다.교환; 이중을 수정하는 것이 정수를 수정하는 것보다 더 복잡한 작업이기 때문인 것 같습니다.아직도 왜 그런지는 확실하지 않습니다, 만약 비교한다면.교환 및 추가는 둘 다 정수를 사용할 수 있고, 두 개 모두 이중을 사용할 수 없습니다.
다른 사람들은 "왜?"를 언급했습니다. 직접 것은 .Add(ref double, double)
사용CompareExchange
원시:
public static double Add(ref double location1, double value)
{
double newCurrentValue = location1; // non-volatile read, so may be stale
while (true)
{
double currentValue = newCurrentValue;
double newValue = currentValue + value;
newCurrentValue = Interlocked.CompareExchange(ref location1, newValue, currentValue);
if (newCurrentValue.Equals(currentValue)) // see "Update" below
return newValue;
}
}
CompareExchange
을 설합니다의 합니다.location1
되려고newValue
이 현재 값같 은경 우이경과 같으면currentValue
원자적이고 스레드 안전한 방식으로 그렇게 하기 때문에 우리는 잠금 장치에 의존하지 않고 단독으로 의존할 수 있습니다.
왜 하필이면while (true)
루프? 낙관적으로 동시 알고리즘을 구현할 때는 이와 같은 루프가 표준입니다. CompareExchange
되지 않음 변되지않location1
이 현재값 와다경과 다른 currentValue
을 했습니다.currentValue
location1
읽기것일 수 않음)를입니다.CompareExchange
값을 확인합니다.현재 값(여전히)이 우리가 읽은 값일 경우location1
,CompareExchange
이 값이 다으변경니다됩로음다로 됩니다.newValue
그렇지 않으면 다시 시도해야 합니다.CompareExchange
값을 하여 반된 전류값로에서 CompareExchange
.
번 다 스 값 까 지 다 스 의 에 변 해 경 된 경 우 드 레 음 른 레 드 이 ▁until 우 ▁the ▁thread 경 된 ▁if ▁by ▁is 경 변 ▁next ▁value ▁the ▁changed ▁another ▁of 다 음 ▁timeCompareExchange
다시, 그것은 다시 실패할 것이고, 또 다른 재시도가 필요합니다 - 그리고 이것은 이론적으로 영원히 계속될 수 있습니다, 따라서 루프.여러 스레드에서 값을 지속적으로 변경하지 않는 한,CompareExchange
현재 값이 여전히 의 비휘발성 판독치인 경우 한 번만 호출될 가능성이 높습니다.location1
만약 그것이 달랐다면, 두 번 양보했습니다.
2022/8/17 업데이트
Strangelove 박사와 Theodor Zoulias가 댓글에서 지적했듯이, 언제.location1 == Double.NaN
무한Add()
루프로 변할 수 있습니다.
그래서 옷을 갈아입어야 했습니다.
if (newCurrentValue == currentValue)
로.
if (newCurrentValue.Equals(currentValue))
Interlocked 클래스는 Windows API Interlocked** 함수를 감싼다.
이것들은 차례로 x86에 대한 LOCK 명령어 접두사를 사용하여 네이티브 프로세서 API를 감싸고 있습니다.다음 지시사항 접두사만 지원합니다.
BT, BTS, BTR, BTC, XCHG, XADD, ADD, OR, ADC, SBB, AND, SUB, XOR, NOT, NEG, INC, DEC
여러분은 이것들이 결국 연동된 방법들과 거의 일치한다는 것을 알게 될 것입니다.유감스럽게도 정수가 아닌 유형의 ADD 기능은 여기에서 지원되지 않습니다.64비트 플랫폼에서 64비트 길이에 대한 추가가 지원됩니다.
다음은 명령 수준에서 잠금 의미론을 논의하는 훌륭한 기사입니다.
Reed Copsey가 말했듯이 인터락된 운영 맵은 (Windows API 기능을 통해) x86/x64 프로세서에서 직접 지원하는 명령어에 매핑됩니다.이러한 기능 중 하나가 XCHG라는 것을 고려할 때, 목표 위치의 비트가 무엇을 나타내는지 신경 쓰지 않고 원자 XCHG 연산을 수행할 수 있습니다.즉, 코드는 교환하는 64비트 부동소수점 번호가 실제로 64비트 정수인 것처럼 " 가장"할 수 있으며, XCHG 명령어는 그 차이를 알지 못합니다.따라서.Net은 Interlocked를 제공할 수 있습니다.플로트에 대한 교환 함수와 각각 정수와 긴 정수인 것처럼 "시늉"하여 두 배로 증가합니다.
그러나 다른 모든 작업은 실제로 대상의 개별 비트에서 작동하므로 값이 실제로 정수(또는 경우에 따라 비트 배열)를 나타내지 않는 한 작동하지 않습니다.
저는 두 가지 이유가 있다고 생각합니다.
- 대상이 되는 프로세서.정수 유형에 대해서만 NET 지원 연동 증분.저는 이것이 x86의 LOCK 접두사라고 생각합니다. 아마도 다른 프로세서에도 비슷한 지침이 있을 것입니다.
- 부동 소수점 번호에 하나를 추가하면 충분히 큰 경우 동일한 숫자가 발생할 수 있으므로 이를 증분이라고 할 수 있을지 모르겠습니다.아마도 프레임워크 설계자들은 이 경우 직관적이지 않은 행동을 피하려고 할 것입니다.
언급URL : https://stackoverflow.com/questions/1400465/why-is-there-no-overload-of-interlocked-add-that-accepts-doubles-as-parameters
'programing' 카테고리의 다른 글
클릭 이벤트가 동적으로 생성된 요소에서 작동하지 않음 (0) | 2023.05.08 |
---|---|
linq를 사용하여 고유 선택 (0) | 2023.05.08 |
날짜 시간 대 날짜 시간 오프셋 (0) | 2023.05.08 |
디렉터리를 반복적으로 순환하여 특정 확장명의 파일을 삭제하는 방법 (0) | 2023.05.08 |
PostgreSQL에서 가로 조인과 하위 쿼리의 차이점은 무엇입니까? (0) | 2023.05.08 |