이 글은 기계 번역의 미러 문서이며, 원본 기사로 바로 이동하려면 여기를 클릭해 주세요.

보기: 46741|회답: 7

[출처] 볼라타일 vs. 인터록드 vs. 락

[링크 복사]
게시됨 2018. 8. 27. 오후 2:40:35 | | |
예를 들어, 여러 스레드가 접근할 수 있는 공개 정액 카운터 필드를 포함하는 클래스가 있다고 가정해 봅시다. 이 수치는 오르거나 줄어들 뿐입니다.

이 필드를 추가할 때, 다음 스킴 중 어떤 것을 사용해야 하며, 그 이유는 무엇인가요?

  • lock(this.locker) this.counter++;
  • 상호 고정. 증분(참조 this.counter);
  • 카운터의 접근 수정자를 공개 변동성으로 변경하세요


최악의 경우(실제로 효과가 없는 것)

카운터의 접근 수정자를 공개 변동성으로 변경하세요

이 방법은 사실 전혀 안전하지 않으며, 휘발성 모드의 핵심은 여러 CPU에서 실행되는 여러 스레드가 데이터를 버퍼링하고 실행된 명령어를 재배열한다는 점입니다.

비휘발성이라면, CPU A가 값이 증가하면 CPU B가 증가한 값을 보기 위해 일정 시간이 필요해 문제가 발생할 수 있습니다.

만약 휘발성 데이터가 있다면, 두 CPU가 동시에 같은 값을 보도록 보장합니다. 하지만 읽기와 쓰기 연산을 교차 편집하는 것을 피하지는 않습니다.

변수에 가치를 더하는 데는 실제로 세 단계가 필요합니다

1. 독서, 2. 덧셈 3. 쓰기

스레드 A가 카운터의 값을 1로 읽고 증가할 준비가 되지 않았다고 가정하자, 스레드 B도 카운터의 값을 1로 읽고, 두 스레드 모두 증분 및 쓰기 작업을 수행하기 시작한다. 최종 카운터의 가치는 2입니다. 이것은 옳지 않습니다. 두 스레드 모두 증가 연산을 수행했으며, 올바른 결과는 3이어야 합니다. 따라서 이를 변동성 있다고 분류하는 것은 단순히 안전하지 않습니다.

더 좋아

lock(this.locker) this.counter++;

이렇게 하면 안전합니다 (물론 이 카운터에 접근하려면 모든 곳을 잠그세요). 다른 스레드가 잠긴 코드를 실행하는 것을 방지합니다. 또한 앞서 언급한 다중 CPU 명령어 순서 문제도 방지합니다. 문제는 lock이 성능이 느리고, 다른 다른 곳에서 lock을 사용하면 다른 스레드가 차단될 수 있다는 점입니다.

최고의

상호 고정. 증분(참조 this.counter);

이것은 안전하고 매우 효율적입니다. 이 장치는 한 원자에서 중간에 중단되지 않고 읽기, 증가, 쓰기 세 번의 연산을 수행합니다. 다른 코드에는 영향을 주지 않기 때문에 다른 곳에서 자물쇠를 기억할 필요가 없습니다. 그리고 매우 빠릅니다(MSDN에 따르면 오늘날 CPU에서는 종종 명령어만 처리됩니다).

하지만 CPU의 명령어 순서 문제도 해결할 수 있는지, 아니면 휘발성 함수와 이 증분과 함께 사용해야 하는지 확신이 서지 않습니다.

보충: 볼라타일이 잘 해결하는 문제는 무엇인가요?

volatile이 멀티스레딩을 막을 수 없다면, 무엇을 할 수 있을까요? 좋은 예로, 두 개의 스레드가 있는데, 하나는 항상 변수(예를 들어 queneLength)에 쓰고, 다른 하나는 항상 이 변수에서 데이터를 읽습니다. 만약 queueLenght가 변동성이 아니라면, 스레드 A는 5번 읽을 수 있지만, 스레드 B는 지연된 데이터나 심지어 잘못된 순서의 데이터를 볼 수 있습니다. 한 가지 해결책은 락을 사용하는 것이지만, 이 경우에는 볼라타일도 사용할 수 있습니다. 이렇게 하면 스레드 B가 항상 스레드 A가 작성한 최신 데이터를 볼 수 있지만, 이 논리는 쓰기 시 읽지 않고, 읽을 때 쓰지 않을 때만 작동합니다. 여러 스레드가 읽기-수정-쓰기 작업을 하려 할 때는 Interlocked 또는 lock을 사용해야 합니다.





이전의:Java MD5 암호화 방법
다음:Linq는 SQL의 조건부 쿼리와 조건부 쿼리 모두에서 구현합니다
게시됨 2018. 8. 29. 오후 4:21:42 |
안녕하세요, 이전에 작성하신 하이차트 스택 히스토그램과 드릴 가능한 히스토그램을 결합한 코드인가요? https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light 인터페이스에서 편집할 수 있는 코드를 보내주실 수 있는지 여쭤보고 싶습니다.
게시됨 2018. 8. 29. 오후 4:22:13 |
전체 네트워크가 당신의 자원일 뿐입니다.
게시됨 2018. 8. 29. 오후 4:22:55 |
90년 전 사람들은 메시지를 남길 수 없었기 때문입니다. 그래서.
게시됨 2018. 8. 29. 오후 4:40:40 |
연락처 정보를 추가하는 것이 편리한가요? 상담하세요
 집주인| 게시됨 2018. 9. 15. 오후 1:10:16 |
private static int safeInstanceCount = 0; 원자 조작
System.Threading.Interlocked.Increment(ref safeInstanceCount); 자기 증가 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); 자기 마이너스 1
게시됨 2020. 5. 21. 오후 4:43:54 |
소유자가 공유하도록 지원하세요
 집주인| 게시됨 2020. 6. 11. 오후 3:00:16 |
1. 개념

다중 스레드 환경에서는 스레드 스케줄링 메커니즘에 의해 중단되지 않는 작업들; 이 작업이 시작되면 종료 시점까지 실행되며, 그 사이에 컨텍스트 전환(다른 스레드로 전환)이 없습니다.

2. 계급

System.Threading.Interlocked static 클래스

3. 일반적으로 사용되는 함수들 (나머지 참조)

1. public static int 감소(참조 int 위치); 지정된 변수의 값을 원자 연산 형태로 변환하고 결과를 저장합니다

lock(obj){i--; }

2. 공개 정적 int Increment(참조 int 위치); 지정된 변수의 값을 원자 연산 형태로 증가시키고 결과를 저장합니다

lock(obj){i++; }
면책 조항:
Code Farmer Network에서 발행하는 모든 소프트웨어, 프로그래밍 자료 또는 기사는 학습 및 연구 목적으로만 사용됩니다; 위 내용은 상업적 또는 불법적인 목적으로 사용되지 않으며, 그렇지 않으면 모든 책임이 사용자에게 부담됩니다. 이 사이트의 정보는 인터넷에서 가져온 것이며, 저작권 분쟁은 이 사이트와는 관련이 없습니다. 위 내용은 다운로드 후 24시간 이내에 컴퓨터에서 완전히 삭제해야 합니다. 프로그램이 마음에 드신다면, 진짜 소프트웨어를 지원하고, 등록을 구매하며, 더 나은 진짜 서비스를 받아주세요. 침해가 있을 경우 이메일로 연락해 주시기 바랍니다.

Mail To:help@itsvse.com