2009-04-19 2 views
3

여러 번 언급 된 코드 조각을 보았습니다. Max(a+1, a-1)의 요점은 무엇입니까? 처음에는 언더 플로우를 막을 수있을 것이라고 생각했지만,이 경우 언더 플로우를 방지하지 않는 것이 실제로 의미가 없습니다.Max (Threading.Interlocked.Increment (Offset), Offset - 1)의 요점은 무엇입니까?

+0

코드 샘플을 http://www.google.com/search?q=Max+Threading.Interlocked.Increment – sisve

+0

감사 사이먼에서 : 거기에 다음과 같은 C# 코드를 입력 시도하고 VB.NET로 변환 이 코드가 어디에서 왔는지에 대한 정보를 포인터에 기반한 내 답변에 추가했습니다. –

답변

4

언급했듯이 Offset이 0으로 감싸는 (또는 음수가되는) 경우를 감지하고 어떤 유형이든 Offset 인 경우 최대 값으로 고정되도록 할 수 있습니다. 또는 그들은 복수 스레드 (또는 무언가)에서 Offset이 '동시에'증가되는 상황을 처리하려고 시도 할 수 있습니다.

두 경우 모두 버그가있는 코드입니다.

0 또는 음수로 감싸기를 감지하거나 방지하려는 경우 너무 많은 증분으로 인해 문제가 발생할 수 있습니다. 그들이 '동시에'증가하는 Offset을 처리하려고하는 경우, 나는 그들이 어떤 문제를 해결하려고하는지 또는 어떻게 해결하려고하는지 명확하지 않습니다.

As Jon Skeet says : - 오프셋은 휘발성이 아닌, 후자의 표현 어쨌든 최신 값을 얻을 수 있기 때문에

그러나, 여전히 나에게 이상한 소리

는 여기에 문제가 있습니다.

그러나 그것보다 더 나쁘다조차 - Offset 그것을 증가 될 수있는 또 다른 스레드와 Offset의 새로운 값을 읽는 직렬화 아무것도 휘발성 경우에도, 그래서 매우 인스턴트 Max() 표현 값을 재 - 읽기 후 Offset의 다른 스레드 수에 관계없이 원하는만큼의 스레드가 증가 할 수 있습니다. 그러니 표현은 쓸모가 없지만, 그 기술을 사용하는 것은 해를 끼칠 수 있습니다. 왜냐하면 여러분에게 '속한'것이 아닌 Offset의 값을 사용하게 될 수 있기 때문입니다.

Offset을 사용하여 배열 색인이나 어떤 것을 추적하는 경우를 생각해 봅니다. Offset을 원자 적으로 증가 시키면 해당 인덱스에있는 배열 요소가 사용됩니다. 질문 에서처럼 Max() 표현식을 사용하면 실제로 다른 스레드에 속한 배열 요소가 갑자기 엉망이 될 수 있습니다.

말했듯이 내가 정당한 이유를 생각할 수 없다

은 가장 잘 무해 (쓸모없는)이다,

Max(Threading.Interlocked.Increment(Offset), Offset - 1) 

를 사용하지만 매우 하드가 문제를 진단하는 데 들어갈 수 있습니다 - 을 사용하지 마십시오. 질문의 사용에 대한 Google 검색을 지적 사이먼 스벤손에 의해 코멘트에


감사합니다, 그것은 (? 항상) 일반적으로이 코드처럼 보이는 VB.NET 변환기는 C#의 출력에서 ​​온다. 이 표현식을 사용하여 로컬 변수를 증가시킵니다 (스레딩은 문제가되지 않습니다). Offset이 로컬 변수 인 경우이 표현식은 쓸모 없지만 대부분 무해한 다양성을 갖습니다 (증분이 줄 서면 '버그'가 있음). 실제로 다소 비효율적 인 Offset++ 표현식입니다 (실제로 변환기가 C# 표현식 Offset++을 VB.NET으로 변환하는 방법 인 것처럼 보입니다 - http://www.telerik.com/community/forums/open-source-projects/code-converter/added-value.aspx#307755 참조). 실제로이 변환은 Offset++에 대해 버그가 있습니다. 증분하기 전에 값이 반환되어야 할 때 증분 된 값을 반환하기 때문입니다.

정말 나쁜 점은 다른 사람이 해당 코드를보고 "Interlocked.Increment()을 사용해야하는 방식"이라고 생각할 수 있다는 것입니다.

2

Max(a, a-1)과 같지 않습니다. Interlocked.Increment으로 전화가 왔기 때문입니다. 다른 스레드가 Interlocked.Increment이라는 호출과 Offset-1의 호출 사이에서 Offset 값을 변경한다고 가정합니다.

그러나 여전히 이상하게 들립니다. 왜냐하면 Offset이 휘발성이 아니기 때문에 후자의 표현식이 최신 값을 얻지 못할 수 있기 때문입니다.

Interlocked.Increment에 매개 변수가 ref 매개 변수이기 때문에, 코드가없는 매우

Math.Max(Interlocked.Increment(Offset), Offset-1) 

할 수있는 모든이를 가졌어요. 가장 가까운 법적 코드는 다음과 같습니다

Math.Max(Interlocked.Increment(ref Offset), Offset-1) 

당신이 컨텍스트 우리가 할 수있는 정확한 코드 을 보여줄 수 있다면 아마

(그것은 파스칼 맡았다 변수를 의미로이 여전히 ... 이상한 것) 요점을 해결하십시오. 나는 그런 코드를 직접 본 적이 없다고 말할 수 없다.

+0

코드를 처음 본 곳을 잊어 버렸습니다. 소켓에 관한 기사를 읽는 동안 생각한 것입니다. 하지만 스 니펫에 대한 구글에서 빠른 검색은 사용중인 코드의 많은 예제를 제공합니다. –

+0

그런 다음 하나를 선택하고 질문을 업데이트하고 일반성 대신 구체적인 예를 논의 할 수 있습니다. –

+0

@ 존, 나는 VB .NET에서는 ref 키워드를 사용하지 않습니다. http://www.google.com/search?q=Max+Threading.Interlocked.Increment에서 this ... techn/myst-ique를 사용하는 코드 샘플을 확인하십시오. – sisve

1

Interlocked.Increment(a)은 원자 값으로 a의 값을 증가시킵니다. 단일 스레드 응용 프로그램에서는 a++과 동일하지만 다소 느립니다. 다중 스레드 응용 프로그램에서는 두 스레드가 값을 증가시킬 때 상호간에 간섭하지 않고 스레드가 값을 증가 시키도록합니다. 자세한 내용은 MSDN reference page을 참조하십시오.

더 많은 코드가 표시되지 않는 이유는이 컨텍스트에서 사용되는 이유입니다.

5

구글 검색은 약간의 (아마도 버그가 많은) C#에서 VB.NET 변환기 소프트웨어로 발생할 수 있다는 의구심을 갖습니다. 그것은 그것의 빈번한 출현을 설명 할 것입니다.

추가 : Yessss, I found it! 나는 -

int i; 
i++; 
+0

wow that wierd – Davy8

관련 문제