[multithreading] “스레드 안전”이라는 용어의 의미는 무엇입니까?

두 개의 스레드가 기본 데이터를 동시에 변경할 수 없다는 것을 의미합니까? 아니면 여러 스레드가 해당 코드 세그먼트를 실행할 때 주어진 코드 세그먼트가 예측 가능한 결과로 실행된다는 것을 의미합니까?



답변

Wikipedia에서 :

스레드 안전성은 멀티 스레드 프로그램의 맥락에서 적용 가능한 컴퓨터 프로그래밍 개념입니다. 여러 스레드가 동시에 실행하는 동안 올바르게 작동하면 코드 조각이 스레드로부터 안전합니다. 특히, 여러 공유 스레드가 동일한 공유 데이터에 액세스 할 필요성과 주어진 시간에 하나의 스레드 만 공유 데이터 조각에 액세스 할 필요성을 충족시켜야합니다.

스레드 안전을 달성하는 몇 가지 방법이 있습니다.

재입국 :

한 작업에서 부분적으로 실행하고 다른 작업에서 다시 입력 한 다음 원래 작업에서 다시 시작할 수 있도록 코드를 작성합니다. 이를 위해서는 정적 또는 전역 변수 대신 각 작업의 로컬 변수, 일반적으로 스택에 상태 정보를 저장해야합니다.

상호 배제 :

공유 데이터에 대한 액세스는 언제든지 하나의 스레드 만 공유 데이터를 읽거나 쓰도록하는 메커니즘을 사용하여 직렬화됩니다. 코드 조각이 여러 공유 데이터 조각에 액세스하는 경우 세심한주의가 필요합니다. 문제에는 경쟁 조건, 교착 상태, 라이브 록, 기아 및 여러 운영 체제 교과서에 열거 된 다양한 기타 문제가 포함됩니다.

스레드 로컬 스토리지 :

변수는 지역화되어 각 스레드마다 고유 한 개인 사본이 있습니다. 이러한 변수는 서브 루틴 및 기타 코드 경계에 걸쳐 값을 유지하며, 액세스하는 코드가 재진입 될 수 있더라도 각 스레드에 대해 로컬이므로 스레드 안전합니다.

원자력 운영 :

다른 스레드에 의해 중단 될 수없는 원자 연산을 사용하여 공유 데이터에 액세스합니다. 일반적으로 런타임 라이브러리에서 사용 가능한 특수 기계 언어 명령어를 사용해야합니다. 작업이 원자 적이기 때문에 공유 데이터는 다른 스레드가 액세스하는 내용에 관계없이 항상 유효한 상태로 유지됩니다. 원자 연산은 많은 스레드 잠금 메커니즘의 기초를 형성합니다.

더 읽기 :

http://en.wikipedia.org/wiki/Thread_safety



답변

스레드 안전 코드는 많은 스레드가 동시에 실행하더라도 작동하는 코드입니다.

http://mindprod.com/jgloss/threadsafe.html


답변

더 유익한 질문은 코드가 스레드에 안전하지 않게 만드는 것입니다. 그리고 정답은 4 가지 조건이 있어야한다는 것입니다 … 다음 코드를 상상해보십시오 (그리고 기계 언어 번역).

totalRequests = totalRequests + 1
MOV EAX, [totalRequests]   // load memory for tot Requests into register
INC EAX                    // update register
MOV [totalRequests], EAX   // store updated value back to memory
  1. 첫 번째 조건은 둘 이상의 스레드에서 액세스 할 수있는 메모리 위치가 있다는 것입니다. 일반적으로 이러한 위치는 전역 / 정적 변수이거나 전역 / 정적 변수에서 도달 할 수있는 힙 메모리입니다. 각 스레드는 함수 / 메소드 범위의 지역 변수에 대한 자체 스택 프레임을 가져 오므로 스택에있는 이러한 로컬 함수 / 메소드 변수 otoh는 해당 스택을 소유 한 하나의 스레드에서만 액세스 할 수 있습니다.
  2. 두 번째 조건은 이러한 공유 메모리 위치와 연관된 특성 (종종 불변 이라고 함 )이 있으며 프로그램이 올바르게 작동하기 위해서는 true 또는 유효해야한다는 것입니다. 위의 예에서 속성은 ” totalRequests는 스레드가 증가 문의 일부를 실행 한 총 횟수를 정확하게 나타내야합니다 “. 일반적으로 업데이트가 올바르게 수행 되려면 업데이트가 발생하기 전에이 변하지 않는 특성이 true (이 경우 totalRequests가 정확한 수를 보유해야 함)를 보유해야합니다.
  3. 세 번째 조건은 실제 업데이트의 일부 부분에서 고정 속성이 유지되지 않는 것입니다. (일부 처리 중에 일시적으로 유효하지 않거나 거짓입니다). 이 특정 경우, totalRequests가 페치 된 시간부터 갱신 된 값이 저장 될 때까지 totalRequests는 불변을 만족 시키지 않습니다 .
  4. 레이스가 발생하고 코드 가 “스레드 안전”상태가 되지 않기 위해 발생해야하는 네 번째이자 마지막 조건 은 불변이 깨지는 동안 다른 스레드가 공유 메모리에 액세스 할 수 있어야 하므로 불일치 또는 잘못된 행동.

답변

나는 Brian Goetz의 Java Concurrency의 정의가 포괄적이라는 점을 좋아합니다.

“클래스는 런타임 환경에 의한 스레드 실행의 스케줄링 또는 인터리빙에 관계없이 호출 스레드의 일부에 대한 추가 동기화 또는 기타 조정없이 여러 스레드에서 액세스 될 때 올바르게 작동하는 경우 스레드로부터 안전합니다. “


답변

다른 사람들이 지적했듯이 스레드 안전은 한 번에 두 개 이상의 스레드가 사용하는 경우 코드가 오류없이 작동한다는 것을 의미합니다.

때때로 컴퓨터 비용과 복잡한 코딩 비용이 발생하기 때문에 항상 바람직하지는 않습니다. 하나의 스레드에서만 클래스를 안전하게 사용할 수 있다면 그렇게하는 것이 좋습니다.

예를 들어, 자바는 거의 동등한 두 개의 클래스를 가지고 StringBufferStringBuilder. 차이점은 StringBuffer스레드로부터 안전하므로 StringBuffer한 번에 여러 스레드에서 단일 인스턴스를 사용할 수 있다는 것입니다. StringBuilder스레드로부터 안전하지 않으며 String이 하나의 스레드만으로 빌드 될 때 이러한 경우 (대부분의 경우)를위한 고성능 대체물로 설계되었습니다.


답변

스레드 안전 코드는 다른 스레드가 동시에 입력하더라도 지정된대로 작동합니다. 이는 종종 중단없이 실행해야하는 내부 데이터 구조 또는 작업이 동시에 다른 수정으로부터 보호됨을 의미합니다.


답변

이해하기 쉬운 방법은 코드를 스레드로부터 안전하지 않게 만드는 것입니다. 스레드 응용 프로그램이 원치 않는 동작을하게하는 두 가지 주요 문제가 있습니다.

  • 잠금없이 공유 변수에 액세스이 변수
    는 기능을 실행하는 동안 다른 스레드에서 수정할 수 있습니다. 기능의 동작을 확인하기 위해 잠금 메커니즘으로이를 방지하려고합니다. 일반적으로 가장 짧은 시간 동안 잠금을 유지하는 것이 좋습니다.

  • 공유 변수에 대한 상호 종속성으로 인한 교착 상태
    두 개의 공유 변수 A와 B가있는 경우 한 함수에서 A를 먼저 잠근 다음 나중에 B를 잠급니다. 다른 함수에서는 B를 잠그고 잠시 후 A를 잠급니다. 는 두 번째 기능이 A 잠금 해제를 기다릴 때 첫 번째 기능이 B 잠금 해제를 기다릴 수있는 잠재적 교착 상태입니다. 이 문제는 개발 환경에서 발생하지 않으며 때때로 만 발생합니다. 이를 방지하려면 모든 잠금 장치는 항상 같은 순서로되어 있어야합니다.