멀티 스레드 경쟁 조건 테스트


54

답변에 대한 의견을 읽으십시오 .

테스트를 작성할 수 없다고해서 테스트가 중단되지 않았다는 의미는 아닙니다. 일반적으로 예상대로 작동하는 정의되지 않은 동작 (C 및 C ++에는이 기능이 가득 함), 경쟁 조건, 메모리 모델이 약하여 잠재적 인 순서 변경 ... – CodeInChaos 7 시간 전

@CodesInChaos 만약 그것이 재현 될 수 없다면 'fix'에 쓰여진 코드도 테스트 될 수 없습니다. 그리고 테스트되지 않은 코드를 라이브에 넣는 것은 제 생각에 더 나쁜 범죄입니다 – RhysW 5 시간 전

... 테스트 케이스의 경쟁 조건으로 인해 발생하는 생산 문제에서 매우 드물게 발생하는 일반적인 방법이 있는지 궁금합니다.


1
양끝에 지시에 의해 단계를 조립 (조립)
래칫 괴물

1
정적 분석은 종종 잠재적 인 UB를 보여줄 수 있지만 이것이 테스트로 계산되는지 명확하지 않습니다
jk.

물어봐서 죄송하지만 'UB'는 무엇을 의미합니까?
Doug

2
좋은 질문, 나는 이것에 대한 잠재적 인 해결책을 보는 데 흥미로울 것입니다.
RhysW

1
@Doug Undefined Behaviour는 경쟁 조건
jk

답변:


85

1978 년 이래로이 미친 사업에 종사 한 후 임베드 된 실시간 컴퓨팅, 멀티 태스킹, 멀티 스레드, 다중 시스템, 때로는 여러 물리적 프로세서로 작업하면서 거의 모든 시간을 레이스에서 경쟁했습니다. 조건, 내가 생각하는 의견은 귀하의 질문에 대한 답변이 매우 간단하다는 것입니다.

아니.

테스트에서 경쟁 조건을 유발할 수있는 일반적인 방법은 없습니다.

유일한 희망은 시스템에서 완전히 설계하는 것입니다.

다른 사람이 들어간 것을 발견하면 개미집 밖으로 내 던져서 제거하도록 재 설계해야합니다. 시스템에서 그의 가짜 pas (f *** up로 발음)를 디자인 한 후에는 개미에서 그를 풀어 놓을 수 있습니다. (개미가 이미 뼈를 남기고 이미 소비했다면 "이것은 경쟁 조건을 XYZ 프로젝트에 넣는 사람들에게 일어난 일입니다!"라는 표시를 남기고 그대로 두십시오.)


22
완전히 동의 해. 다시 말해, 이것은 농담과 매우 흡사합니다. 환자 : "의사, 내가 이렇게하면 아파요 ..."의사 : "그럼 그만해!"
Mark Rushakoff

좋은 대답입니다. 테스트 할 수없는 문제가 발생하는 경우, 먼저 문제를 해결하고 문제를 피하십시오.
RhysW

내 유일한 질문은 : 개미집을 얼마나 크게 사용해야합니까? (+1 BTW).
Peter K.

15
가짜 pas 의 정확한 발음을 위해 +1 . (그리고 나머지 답변)
Blrfl

1
@PeterK는.,이 더 큰는 모니터, RAM 및 디스크 드라이브와 함께, 소프트웨어 개발에 그 몇 가지 경우 중 하나 입니다 더 나은.
John R. Strohm

16

ms 도구 체인에있는 경우 MS 리서치는 각 런마다 새로운 인터리빙을 강제하고 실패한 런을 체스 라고하는 툴을 개발했다 .

다음은 사용중인 비디오 입니다.


5
인상적입니다. 어느 시점에서 시도해 볼 시간을 찾아야합니다.
Dan Neely

16

이러한 종류의 문제에 대해 내가 아는 가장 좋은 도구는 Helgrind 라는 Valgrind의 확장입니다 .

기본적으로 Valgrind는 가상 프로세서를 시뮬레이션하고 그 위에서 바이너리 (수정되지 않은)를 실행하므로 메모리에 대한 모든 단일 액세스를 확인할 수 있습니다. 이 프레임 워크를 사용하여 Helgrind watch 시스템은 공유 변수에 대한 액세스가 상호 배제 메커니즘에 의해 제대로 보호되지 않을 때 추론하도록 요청합니다. 그렇게하면 실제로 발생하지 않았더라도 이론적 경쟁 조건을 감지 할 수 있습니다.

인텔은 인텔 인스펙터 라는 매우 유사한 도구를 판매합니다 .

이러한 도구는 훌륭한 결과를 제공하지만 분석하는 동안 프로그램 속도가 상당히 느려집니다.


1
Valgrind는 여전히 * nix 전용 도구입니까?
Dan Neely

1
예, Linux, MacOSX, Android 및 일부 BSD : valgrind.org/info/platforms.html
Julien

1
ThreadSanitizer는 비슷한 도구입니다. Helgrind와는 다르게 작동하므로 훨씬 빠르다는 장점이 있지만 툴체인에 통합해야합니다.
Sebastian Redl

7

멀티 스레딩 버그를 노출하려면 서로 다른 실행 스레드가 특정 인터리브 순서로 단계를 수행해야합니다. 일반적으로이 인터리빙을 제어하기 위해 일종의 "핸들"을 얻기 위해 수동 디버깅이나 코드 조작 없이는 수행하기가 어렵습니다. 그러나 예측 불가능하게 작동하는 코드를 변경하면 예측 불가능성에 종종 영향을 미치므로 자동화하기가 어렵습니다.

Jaroslav Tulach는 실용적인 API 디자인 에서 유용한 트릭을 설명합니다 . 문제가되는 코드에 로깅 문이있는 경우 해당 로깅 문 소비자 (예 : 주입 된 의사 터미널)를 조작하여 특정 로그 메시지를 특정하게 받도록합니다. 그들의 내용에 따라 주문하십시오. 이를 통해 아직 존재하지 않는 프로덕션 코드에 아무것도 추가하지 않고도 다른 스레드에서 단계의 인터리빙을 제어 할 수 있습니다.


2
주입 된 저장소를 사용하기 전에 비슷한 순서로 호출하여 스레드를 특정 순서로 호출하여 원하는 인터리브를 강제로 수행합니다. 코드를 작성하면 위의 @John의 답변이 +1되는 경향이 있습니다. 진지하게,이 물건은 올바르게 사용하기가 너무 고통스럽고, 다른 결과를 가진 약간 다른 인터리브가있을 수 있기 때문에 최고의 추측 보장만을 제공합니다. 더 나은 접근 방법은 정적 분석 및 모든 공유 상태에 대한 코드의 신중한 조합을 통해 가능한 모든 경쟁 조건을 제거하는 것입니다.
Jimmy Hoffa

6

다양한 종류의 정의되지 않은 동작 (특히 경쟁 조건)이 존재하지 않는다는 것을 절대 확신 할 수있는 방법이 없습니다.

그러나 그러한 상황을 잘 보여주는 여러 가지 도구가 있습니다. 수정 사항이 유효하다는 것을 증명할 수는 없지만 현재 이러한 도구에 문제가 있음을 증명할 수 있습니다.

이 목적을위한 몇 가지 흥미로운 도구 :

Valgrind는 메모리 검사기입니다. 메모리 누수, 초기화되지 않은 메모리 읽기, 매달려있는 포인터 사용 및 범위를 벗어난 액세스를 찾습니다.

Helgrind는 스레드 안전 검사기입니다. 경쟁 조건을 찾습니다.

둘 다 동적 계측에 의해 작동합니다. 즉, 프로그램을있는 그대로 가져와 가상화 된 환경에서 실행합니다. 이렇게하면 방해가되지 않지만 느려집니다.

UBSan은 정의되지 않은 동작 검사기입니다. 정수 오버플로, 범위를 벗어난 시프트 및 유사한 것들과 같은 다양한 C 및 C ++ 정의되지 않은 동작을 찾습니다.

MSan은 메모리 검사기입니다. Valgrind와 비슷한 목표를 가지고 있습니다.

TSan은 스레드 안전 검사기입니다. Helgrind와 비슷한 목표를 가지고 있습니다.

이 세 가지는 Clang 컴파일러에 내장되어 있으며 컴파일시 코드를 생성합니다. 즉, 빌드 프로세스에 통합해야하며 (특히 Clang으로 컴파일해야 함) 초기에 * grind보다 설정하기가 훨씬 어렵지만 반면에 런타임 오버 헤드는 훨씬 낮습니다.

내가 나열한 모든 도구는 Linux에서 작동하고 일부는 MacOS에서 작동합니다. 아직 Windows에서 안정적으로 작동하지 않는다고 생각합니다.


1

여기에있는 대부분의 답변은이 질문을 "경쟁 조건을 자동으로 어떻게 감지합니까?"라고 잘못 생각하는 것 같습니다. 문제는 "테스트에서 레이스 조건을 찾을 때 어떻게 테스트합니까?"

이를 수행하는 방법은 테스트에만 사용되는 코드에 동기화를 도입하는 것입니다. 예를 들어, 이벤트 X가 이벤트 A와 이벤트 B 사이에있을 때 경쟁 조건이 발생하면 응용 프로그램을 테스트하기 위해 이벤트 A가 발생한 후 이벤트 X가 발생할 때까지 기다리는 코드를 작성하십시오. 테스트를 위해 애플리케이션과 대화 할 수있는 방법이 필요할 것입니다 ( "이것은 테스트 중이므로이 위치에서이 이벤트를 기다립니다").

node.js와 mongo를 사용하고 있는데 일부 작업에는 여러 컬렉션에서 일관된 데이터를 만드는 것이 포함됩니다. 이 경우, 단위 테스트는 응용 프로그램을 호출하여 "이벤트 X에 대한 대기 설정"을 알리고 응용 프로그램이 설정 한 후에는 이벤트 X에 대한 테스트를 실행 한 후 테스트에 지시합니다. 응용 프로그램 ( "이벤트 X 대기 중입니다")으로 나머지 테스트가 정상적으로 실행됩니다.

여기에 대한 답변은 파이썬의 맥락 에서이 유형의 것을 자세히 설명합니다 : https : //.com/questions/19602535/how-can-i-reproduce-the-race-conditions-in-this-python-code- 확실하게

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.