문제

당신은 무엇을 의미하는 원자 지?

은 어떻게 다음이 될 원자?

TestAndSet

int TestAndSet(int *x){
   register int temp = *x;
   *x = 1;
   return temp;
}

에서 소프트웨어의 관점 하면,사용하지 않으려고 비 차단하는 동기화 기본 형식할 수 있는 방법 하나인 자성의 지?은 그것을 가능하에서만 하드웨어 또는 몇 가지 어셈블리 레벨 지시어 최적화를 사용할 수 있습니까?

도움이 되었습니까?

해결책

일부 기계 지침은 본질적으로 원자입니다. 예를 들어, 기본 프로세서의 적절한 정렬 된 값을 읽고 쓰는 것은 원자입니다. 많은 아키텍처에서.

이는 하드웨어 인터럽트, 다른 프로세서 및 하이퍼 스레드가 읽기 또는 저장을 방해하고 동일한 위치에 부분 값을 읽거나 쓸 수 없음을 의미합니다.

원자 적으로 함께 읽고 쓰는 것과 같은 더 복잡한 것들은 명백한 원자 기계 지침 (예 : x86의 cmpxchg)에 의해 달성 될 수 있습니다.

잠금 및 기타 고급 구조는 이러한 원자 원시를 기반으로하며, 일반적으로 단일 프로세서 단어 만 보호합니다.

단일 독자와 작가 사이에 공유 된 링크 된 목록에서 또는 여러 독자 및 작가 간의 링크 된 목록에서 Pointers의 읽기 및 쓰기만으로도 일부 영리한 동시 알고리즘을 구축 할 수 있습니다.

다른 팁

원자에서 온 그리스 ἄτομος(atomos)의미하는"분". (주의:난 말하지 않는 그리스어,그래서 어쩌면 그것은 정말 뭔가 다른 것이지만,대부분의 영어 스피커 인용하는 어원은 그것을 해석하는 이 방법입니다.:-)

컴퓨팅에서,즉,작동,아, .이 없는 중간 상태 표시하기 전에 완료됩니다.그래서 만약 당신의 CPU 가 중단되면 서비스 하드웨어(IRQ),또는 다른 CPU 을 읽고 동일한 메모리에 영향을 미치지 못한 결과,그리고 이러한 다른 작업을 관찰하는 그것으로 완료되거나 시작하지 않습니다.

로 예...말 당신이 원하는 변수를 설정하는 무언가를하지만,경우에만 설정되지 않았다.당신이 있는 경향이 이렇게하려면:

if (foo == 0)
{
   foo = some_function();
}

하지만 만일 이 병렬로 실행?그것은 될 수 있는 프로그램를 가져옵니다 foo, 볼,제로,그 사이에 스레드 2 고 같은 값을 설정합니다.다시 원본 스레드에서,코드는 여전히 생각하 foo 로,그리고 변수정이다.

에 대한 이 같은 경우,CPU 제공하는 일부의 지침을 할 수있는 비교와 조건으로 할당하는 원자 entity.따라서,테스트 및 세트,compare-and-swap 및 부하가 연결되어/저장 조건입니다.당신이 사용할 수 있습을 구현하는 자물쇠(하는 C 라이브러리는 이 프로젝트를 진행했습니다.) 거나 작성할 수 있습 one-off 알고리즘에 의존하는 기본 형식이 뭔가를 할 수 있습니다.(거기에 멋진 물건을 할 여기에,하지만 대부분의 단순한 인간 이해의 두려움을 받고 그것이 잘못입니다.)

원자력은 공유 리소스를 포함하는 모든 형태의 병렬 처리 (데이터 협력 또는 공유 데이터 포함)가있을 때 핵심 개념입니다.

문제는 예로 잘 설명되어 있습니다. 파일을 만들려고하지만 파일이 아직 존재하지 않는 경우에만 파일을 만들려는 두 가지 프로그램이 있다고 가정 해 봅시다. 두 프로그램 중 하나는 언제든지 파일을 만들 수 있습니다.

당신이 그렇게한다면 (당신의 예에있는 것이기 때문에 c를 사용하겠습니다) :

 ...
 f = fopen ("SYNCFILE","r");
 if (f == NULL) {
   f = fopen ("SYNCFILE","w");
 }
 ...

다른 프로그램이 Open for Read와 Open for Write 사이에 파일을 만들지 않았 음을 확신 할 수 없습니다.

직접 할 수있는 방법이 없으며 운영 체제의 도움이 필요합니다. 일반적 으로이 목적을위한 Syncronization Primitives 또는 원자력으로 보장되는 다른 메커니즘 (예 : 잠금 작동이 원자가 인 관계형 데이터베이스입니다. 또는 프로세서 "테스트 및 설정"명령어와 같은 하위 레벨 메커니즘).

중 일부는 아래의 메모에 자성을 이해할 수 있게 도와주는 의미를 파악합니다.노트 소스에서 나와서 내가 읽는 것이 좋습니다 그들 중 일부는 필요하신 경우 자세한 설명보다는 점이 형식으로 글머리 기호입니다.세 어떠한 오류도록 수정할 것입니다.

정의:

  • 그리스에서 의미하는"수없는 작은 부분으로"
  • 는"원자"작업은 항상 관측 수행하 또는 수행하지 않지만, 적 halfway done.
  • 원자 작업이 수행되어야 함 또는 전적으로 수행되지 않습 니다.
  • 멀티 스레드 시나리오는 변수가에서 unmutated 하기 돌연변이 직접 없이"중 돌연변이"값

예제 1:Atomic Operations

  • 다음 사항을 고려 정수를 사용하여 다른 스레드:

     int X = 2;
     int Y = 1;
     int Z = 0;
    
     Z = X;  //Thread 1
    
     X = Y;  //Thread 2
    
  • 위의 예에서,두 개의 스레드를 이용하의 X,Y,Z

  • 각각 읽고 쓰기가 atomic
  • 스레드 경주 할 것이다:
    • 면 쓰레드는 1wins,다음 Z=2
    • 만약 thread2wins,다음 Z=1
    • Z 것입니다 확실히 하나의 이 두 값이

예제 2:Non-Atomic Operations:++/--Operations

  • 고려의 증가/감소 식:

    i++;  //increment
    i--;  //decrement
    
  • Operations 번역:

    1. 읽기 i
    2. 증가/감소 읽은 값
    3. 쓰 새로운 값을 다시 나
  • 작업이 각각의 구성 3atomic operations,고 있지 않은 원자 자신
  • 두 개의 시도를 증가시키는 나는 별도의 스레드에서 수 백지를 끼워 넣는 것과 같은 하나의 단위로 잃

예시 3-Non-Atomic Operations:큰 값보다 4-Bytes

  • 을 고려한 다음 변경할 수 없는 구조체:
  struct MyLong
   {
       public readonly int low;
       public readonly int high;

       public MyLong(int low, int high)
       {
           this.low = low;
           this.high = high;
       }
   }
  • 우리가 만드는 분야는 특정 유형의 값 MyLong:

    MyLong X = new MyLong(0xAAAA, 0xAAAA);   
    MyLong Y = new MyLong(0xBBBB, 0xBBBB);     
    MyLong Z = new MyLong(0xCCCC, 0xCCCC);
    
  • 우리는 수정의 필드에는 별도의 스레드 실 없이 안전

    X = Y; //Thread 1                                  
    Y = X; //Thread 2
    
  • 습니다.NET,복사하는 경우 값을 입력,CLR 지 않는 전화 생성자-이동 바이트 중 하나는 원자로 동시에 이용하실 수 있습니다

  • 이 때문에,운영에서 두 개의 스레드가 지금은 네 atomic operations
  • 없는 경우에는 스레드에 안전 적용할 수 있는 데이터 손상
  • 다음 사항을 고려의 실행 순서 작업:

    X.low = Y.low;      //Thread 1 - X = 0xAAAABBBB            
    Y.low = Z.low;      //Thread 2 - Y = 0xCCCCBBBB              
    Y.high = Z.high;    //Thread 2 - Y = 0xCCCCCCCC             
    X.high = Y.high;    //Thread 1 - X = 0xCCCCBBBB   <-- corrupt value for X
    
  • 읽기와 쓰기 보다 큰 값은 32 비트에서 여러 스레드에서 32 비트 운영체제를 추가하지 않고 어떤 종류의 잠금을 조작하기 위해 원자이 발생 가능성이 높 손상 위와 같이 데이터

프로세서 Operations

  • 에 모든 현대적인 프로세서,가정할 수 있습 읽고 쓰는 자연스럽게 정렬되는 기본 유형은 원자로:

    • 1:메모리 버스가 최소한 유형으로 읽거나 쓰
    • 2:CPU 읽기 및 쓰기를 이러한 유형에서 하나의 버스,트랜잭션을 만드는 것이 불가능한 다른 스레드에서 그들을 보고 반 완료된 상태
  • On x86 및 X64 보장은 없는 읽기 및 쓰기보다 더 큰 여덟 바이트를 원

  • 프로세서 공급업체의 원자 작업에 대한 각 프로세서 소프트웨어 개발자의 설명서
  • 에 단일 프로세서의/단 하나 중핵 시스템에서 사용 가능한 표준에 잠금을 방지하는 기술 CPU 에서 지침이 중단되지만,이 비효율적일 수 있습
  • 인터럽트를 비활성화 또 다른 더욱 효율적인 솔루션을 가능한 경우
  • 에서 다중 프로세서/멀티 코어 시스템을 잠금을 사용하지만 단지 하나를 사용하여 명령하거나 비활성화를 중단을 보증하지 않 원자 액세스
  • 원자성에 의해 달성될 수 있습을 보장하는 지침을 사용 assert'잠'신호는 버스에서 다른 프로세서 시스템에 액세스하는 메모리를 동시에

언어 차이

C#

  • C#보장하는 작업에 어떤 내장 값의 형식을 취하는 4 바이트를 원
  • 작업에 가치 유형을 개 이상의 바이트(double,long,etc.) 을 보장하지는 않습 atomic
  • CLI 보장 읽고 쓰는 변수 값의 형식은 크기(또는 작게)프로세서의 자연적인 포인터 크기의 원자
    • Ex-실행 C#64 비트 OS 에서 64 비트 버전의 CLR 수행 읽기와 쓰기의 64 비트 두 배 긴 정수를 자동으로
  • 을 만드는 원자 작업:
    • .NET provodes Interlocked 클래스의 일부분으로 시스템입니다.실을 꿰는 네임스페이스
    • Interlocked 클래스를 제공합 원자 작업과 같은 증가 비교,exchange,etc.
using System.Threading;             

int unsafeCount;                          
int safeCount;                           

unsafeCount++;                              
Interlocked.Increment(ref safeCount);

C++

  • C++표준을 보증하지 않 원자 행동
  • 모든 C/C++작업으로 추정된 비-원자 지정되지 않는 한 컴파일러에 의해 또는 하드웨어 공급 업체-포함하여 32-bit integer 할당
  • 을 만드는 원자 작업:
    • C++11concurrency 라이브러리 포함-Atomic Operations 라이브러리()
    • 원자 라이브러리를 제공합 원자로 형식 템플릿 클래스를 사용하와 함께 당신이 원하는 모든 유형
    • 작업에 원자 종류는 원자고 이렇게 스레드를 안전

구 AtomicCounter
{

   std::atomic< int> value;   

   void increment(){                                    
       ++value;                                
   }           

   void decrement(){                                         
       --value;                                                 
   }

   int get(){                                             
       return value.load();                                    
   }      

}

Java

  • Java 보장하는 작업에 어떤 내장 값의 형식을 취하는 4 바이트를 원
  • 당하 휘발성 갈망과 복식은 또한 보장을 원
  • Java 제공하는 소 툴킷을 지원하는 클래스 잠금 스레드에 안전 프로그래밍에 하나의 변수를 통해 java.util.동시에 이루어 집니다.atomic
  • 이 제공하는 원자 잠금 작업을 기반으로 낮은 수준의 원자 하드웨어 기본 형식과 같은 compare-and-swap(CAS)이라고도 불리는 비교하고 설정:
    • CAS 식-boolean compareAndSet(expectedValue,updateValue);
      • 이 방법은 자동으로 변수를 설정 updateValue 는 경우 그것은 현재 보유하고 expectedValue-보고 진정한 성공에
import java.util.concurrent.atomic.AtomicInteger;

public class Counter
{
     private AtomicInteger value= new AtomicInteger();

     public int increment(){
         return value.incrementAndGet();  
     }

     public int getValue(){
         return value.get();
     }
}


http://www.evernote.com/shard/s10/sh/c2735e95-85ae-4d8c-a615-52aadc305335/99de177ac05dc8635fb42e4e6121f1d2

원자력은 OS에 의해서만 보장 될 수 있습니다. OS는 기본 프로세서 기능을 사용하여이를 달성합니다.

따라서 자신의 TestandSet 기능을 만드는 것은 불가능합니다. (인라인 ASM 스 니펫을 사용할 수 있는지 확실하지 않지만 TestAndSet Mnemonic을 직접 사용할 수 있습니다 (이 진술은 OS 특권으로 만 수행 할 수 있습니다).

편집 :이 게시물 아래의 주석에 따르면 ASM 지시문을 직접 사용하여 자신만의 'BittestandSet'기능을 만들 수 있습니다 (Intel x86에서). 그러나 이러한 트릭이 다른 프로세서에서도 작동하는 경우 명확하지 않습니다.

나는 내 요점을지지한다 : 당신이 attoic 일을하고 싶다면, OS 기능을 사용하고 직접하지 마십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top