2012-02-15 7 views
0

2 개의 스레드가 동시에 같은 객체에 쓰려고하는 코드가 있다면, 디버깅 멀티 스레딩의 이유 중 일부인 컴파일 타임 오류가 발생하지 않습니다. 프로그램이 너무 어렵다. 하지만 이것은 런타임 오류/예외를 생성합니까?디버그 멀티 스레드 프로그램

누구나 좋은 멀티 스레딩 디버그 기술을 제안 할 수 있습니까?

감사합니다.

답변

1

두 개 이상의 다른 스레드 내부에서 동일한 객체에 액세스해도 런타임이나 디버거에서 오류가 발생하지 않지만 의도하지 않은 방식으로 객체를 둘러 쌀 가능성이 가장 큽니다.

멀티 스레드 환경에서 안전하게 처리하는 방법은 뮤텍스와 세마포어를 사용하는 것입니다. 뮤텍스의 경우 wikipedia link을 확인하십시오.

뮤텍스는 일반적으로 개체에 대한 액세스를 한 번에 하나의 스레드로만 제한하려는 경우에 사용됩니다.

세마포어는 세마포어의 활성화/비활성화에 따라 각 스레드가 증가/감소하는 카운터가있는보다 일반적인 경우입니다 (뮤텍스는 실제로 세마포어의 특수한 경우입니다). 세마포어가 0에 도달하면, 세마포어와 그 원인이 된 쓰레드를 잠글 것이다. 세마포어에 대한 자세한 내용은 다음을 참조하십시오. wikipedia page

더 구체적인 조언이 필요하면 타겟팅하는 운영 체제 및/또는 스레드와 관련이있는 이후의 API (뮤텍스 , 세마포어 등)은 OS에 따라 다릅니다.

+0

Lefteris, 답장을 보내 주셔서 감사합니다. Boost 라이브러리를 사용하고 있으며 Windows와 Linux 모두에서 교차 플랫폼 응용 프로그램을 만들려고합니다. 저는 꽤 멀티 스레드 프로그래밍에 익숙하지 않습니다. 다른 인터 커뮤니케이션 기술에 대해서는 매우 혼란 스럽습니다. 앞서 언급 한 뮤텍스 및 세마포는 메시지 대기열을 사용하는 동기화에 대해서도 들었습니다. 어떤 "표준"접근법이 있는지 궁금합니다. 감사합니다. – 2607

+0

이것이 내가 달성하고자하는 것입니다. 나는 M 객체의 벡터를 가지고 있고, 각 객체는 N 개의 멤버 변수를 가지고있다. X 스레드가 있으며 각각은 벡터 내부의 모든 객체의 멤버 변수에 액세스 할 수 있습니다. 나는 이것을 달성하기 위해 노력하고 있으며 또한 최소한의 임계 구역, 즉 매번 가능한 한 적게 차단하는 것을 가지고있다. 감사. – 2607

+0

액세스를 muttualy exclusive하게하려면, N mutex를 사용해야 할 때 하나의 스레드 만 N 멤버 변수 중 하나에 액세스 할 수 있습니다. 나는 boost 라이브러리에 익숙하지 않지만 mutex 기능이 있다고 생각한다. 맞습니까? – Lefteris

1

단일 개체 또는 리소스에 동시에 쓰는 두 개의 서로 다른 스레드가이 개체를 손상시키고이 문제는 경쟁 조건입니다. 다중 스레드 프로그램에서 경쟁 조건은 컴파일 타임 오류 또는 런타임 오류/예외가 아닙니다. 경쟁 조건은 리소스 공유, 즉 프로세스 간 통신을 관리하는 소프트웨어 결함으로, 뒤에서 데이터를 파손하기 때문에 불쾌합니다. 동일한 프로그램을 여러 번 실행하면 결과가 예상 된 결과가되고 다른 시간은 기대했던 결과가되지 않습니다.

상호 배제를 사용하여 스레드의 경쟁 조건 방지. 뮤텍스를 사용할 수있는 객체 또는 리소스가 하나 뿐인 경우, 예는 LCD 디스플레이 또는 단일 객체이며, 그렇지 않은 경우 세마포어를 여러 개 사용하는 경우 4 개의 USB 포트가 있습니다. 리소스는 데이터 및 장치입니다. 데이터는 변수, 객체, 데이터 구조 등입니다. 장치는 LCD 디스플레이, 프린터, USB 포트 등입니다.

프로그램을 순차적 인 단일 스레드로보고 수행해야 할 분리 작업을 결정하면 더 많은 시간 디버깅 문제. 워드 프로세서는 몇 개의 스레드로 구성된 다중 스레드 프로그램입니다. 텍스트 파일을 읽거나, 텍스트를 표시하거나, 텍스트 파일을 저장하거나, 5 분마다 자동 저장하는 스레드의 가상적인 예가 있습니다. 스레드는 수행 할 수있는 작업이어야하며 워드 프로세서의 모든 스레드가 텍스트를 자원으로 인식해야합니다.

이미 코드 또는 검사 값이있는 경우 각 스레드의 객체 앞뒤에 cout 대신 printf 문을 사용하십시오. cout here 대신 printf의 이유를보십시오.

모든 운영 체제에는 프로세스 간 통신이 있지만 API는 다릅니다. Linux는 POSTIX API를 사용하고 Windows는 Win32 또는 Windows API를 사용하지만 동일한 방식으로 사용됩니다.

읽기 자료 http://drdobbs.com/cpp/199200938?pgno=1

^-Summarized 그것은 수도 있고하지 않을 수

0

을 작성 있었는지에 문서의 일부. 동시 수정은 대부분의 스레딩 표준에서 UB이므로 어떤 일이 발생할지에 대해 아무런 보증도하지 않습니다. 일반적으로 간단한 유형의 경우 하나 또는 다른 쓰기가 "승리"합니다. (일부 플랫폼에서는 정렬 된 간단한 유형에 대해이 점을 보장합니다.) 복잡한 유형에서는 "중간"값으로 찢어 지거나 감길 수 있습니다.

동시 기록은 보통 당신이 가지고있는 문제 유형이 아닙니다. 보다 일반적인 경우는 중복 읽기 - 수정 - 쓰기 작업입니다. 예를 들어, 같은 큐 또는 링크 된 목록에 항목을 추가하려고하는 두 개의 스레드에 대해 생각해보십시오. 링크 된 목록에 항목을 추가하면 링크 된 목록이 "끊어지는"시간이있을 수 있으며, 다른 스레드가 링크 된 목록에 액세스하는 경우 (일부분 완료 될 때 수정 중간에) 링크 된 목록에 액세스 할 수 있습니다 폭발하다.

연결리스트의 머리에 항목을 추가는 일반적으로 같은 것을 포함한다 :

object->next = head->next; 
head = object; 

다른 스레드가 두 번째 줄이 시작되기 전에 첫 번째 줄은 완료되지만 이후에 링크 된 목록에 개체를 추가하려고하면

, 결과는 예쁘지 않을 것이다.

1

Linux 또는 OS X를 사용하는 경우 valgrind 도구 (hellgrind 또는 drd) 중 하나를 사용하여 해당 뮤텍스가없는 스레드에 의한 메모리 액세스를 감지 할 수 있습니다.

그러나 이것은 절대 안전한 것은 아니며 사용자의 모든 문제를 파악하는 데 의존하지 않을 것입니다. 공유 리소스에주의해야합니다.

0

실시간으로 멀티 스레드 코드를 디버깅하는 방법에 대해 아무도 대답하지 않은 것으로 보입니다. 정말 어렵습니다. 극도로 짧은 지연만으로도 프로그램이 다르게 동작하고 특정 경쟁 조건이 발생할 때만 오류가 발생할 수 있습니다. Visual Studio가 너무 느린 매우 빠른 추적으로 만 조사 할 수 있습니다. 두 스레드가 동시에 호출 할 때 trace 메소드는 정말 느려집니다.

비 차단 (!) 추적을 메모리에 직접 작성하는 것은 매우 쉽습니다. 정보를 링 버퍼에 씁니다. 내 C++에서 충분하지 않습니다,하지만 C#으로 코드가 다음과 같이 보일 것입니다 :

const int maxMessages = 0x100; 
const int indexMask = maxMessages-1; 
string[] messages = new string[maxMessages]; 
int messagesIndex = -1; 

public void Trace(string message) { 
    int thisIndex = Interlocked.Increment(ref messagesIndex) & indexMask; 
    messages[thisIndex] = message; 
} 

또한 스레드와 타이밍 정보를 수집하고 잘 추적 출력에있다이 방법에 대한 자세한 설명 : CodeProject의 : 실시간으로 멀티 스레드 코드 디버그 1

관련 문제