2010-05-09 3 views
4

두 개의 스레드가 있고 하나는 signal 만 읽고 다른 하나는 signal 만 설정합니다.읽기 전용 스레드와 쓰기 전용 스레드에 대한 뮤텍스를 작성해야합니까?

signal에 대한 뮤텍스를 만들어야하고 그 이유는 무엇입니까?

UPDATE 난 상관 모든 두 개의 스레드가 동시에를 설정/읽기 경우 충돌이 있습니다 여부

당신은 아마 뮤텍스로 일 것이지만, 이것에 대한 원자 변수를 사용하는 것이 좋습니다

답변

2

잘.

문제는 데이터가 스레드간에 동기화된다는 보장이 없지만 원자 변수를 사용하면 한 스레드가 해당 변수를 업데이트하자마자 다른 스레드가 즉시 해당 업데이트 값을 읽게됩니다.

한 스레드가 캐시의 변수를 업데이트하고 두 번째 스레드가 변수를 메모리에서 읽으면 문제가 발생할 수 있습니다. 캐시가 아직 메모리로 플러시되지 않은 경우 두 번째 스레드는 변수의 오래된 값을 읽습니다. 원자 변수는 변수 값이 스레드간에 일관성을 유지하는지 확인합니다.

변수 업데이트를시기 적절하지 않은 경우 휘발성 변수 하나를 제거 할 수 있습니다.

0

스레드간에 동기화가 필요한 경우 (한 스레드는 다른 스레드가 다른 스레드를 시작하려면 먼저 스레드가 완료해야 함) 상호 배제가 필요하지 않아야합니다.

상호 배제는 스레드가 거의 동일한 시간에 임계 영역을 모두 통과 할 경우 리소스가 손상 될 수있는 일부 리소스를 공유 할 때만 필요합니다. 두 사람이 은행 계좌를 공유하고 동시에 두 개의 다른 ATM에 있다고 생각하십시오.

언어/스레딩 라이브러리에 따라 상호 배제 (세마포 또는 모니터)와 동일한 메커니즘을 사용하여 동기화 할 수 있습니다. Pthreads를 사용하는 경우 여기에서 누군가가 동기화 예제를 게시하고 상호 배제에 대한 예제를 게시 할 수 있습니다. 자바라면 다른 예제가있다. 아마도 당신이 사용하고있는 언어/라이브러리를 알려줄 수 있습니다.

+1

WhirlWind 나는 내 반응을 오해했다고 생각합니다. 두 스레드가 자원을 공유하고 있다면 상호 배타의 필요성에 동의합니다. 공유 자원이 없지만 다른 스레드가 다른 스레드를 완료 할 때까지 스레드를 시작할 수없는 경우 상호 배제가 아닌 동기화가 필요하다는 질문을 이해했습니다. –

+0

@ 마크 나는 내가 한 것 같아. 나는 조금 전에 나의 코멘트를 삭제했다. +1 좋은 설명. – WhirlWind

+0

얘들 아, 나는 질문을 업데이트했다. 처음으로 명확히하지 않은 것에 대해 죄송합니다. – httpinterpret

0

편집에서 말했듯이 크래시에 대한 확실한 보장 만하고 싶다면 아무 것도 할 필요가 없습니다 (적어도 규칙은 아님). 스레드간에 충돌이 발생하면 최악의 상황은 데이터가 손상된다는 것입니다. 예를 들어 독자가 부분적으로 업데이트 된 값을 얻을 수 있으며 글쓰기 쓰레드가 작성한 값과 직접적으로 일치하지 않을 수 있습니다 . 고전적인 예는 뭔가를 추가 한 멀티 바이트 숫자이며 캐리가있었습니다 (예를 들어) 이전 값은 0x3f ffff이고 증가되었습니다. 읽기 스레드가 하위 16 비트가 증가되었지만 상위 16 비트의 캐리가 발생하지 않은 0x3f 0000을 볼 수 있습니다 (아직).

최근의 컴퓨터에서 데이터 항목의 작은 부분에 대한 증가분은 일반적으로 원자 적입니다. 그러나 일반적으로 변수의 일부가 하나의 캐시 라인에있는 경우에는 크기 (및 정렬)가 없습니다. 또 다른 부분에서, 그것은 더 이상 원자가되지 않을 것입니다. 정확한 크기와 정렬은 다소 차이가 있지만 기본 아이디어는 동일하게 유지됩니다. 대부분의 경우 숫자가 충분하기 때문에 문제가 발생하지 않습니다.물론

, 당신이 조심하지 않으면, 그 같은 뭔가 순서에 당신의 교착하는 코드 또는 뭔가를 일으킬 수 - 당신이 데이터를 사용할 계획 방법에 대해 아무것도 모른 채 일어날 일에 맞춰 불가능 .

1

에 따라 다릅니다. 쓰기가 원자 적이면 상호 배제 잠금이 필요하지 않습니다. 쓰기가 원 자성이 아니라면 잠금이 필요합니다.

컴파일러가 CPU 캐시에 변수를 캐싱하는 문제가있어서 주 메모리의 복사본이 모든 쓰기에서 업데이트되지 않을 수 있습니다. 일부 언어에는 컴파일러에게 CPU의 변수 (Java의 volatile 키워드)를 캐시하지 않거나 캐시 된 값을 주 메모리 (Java의 동기화 된 키워드)와 동기화하도록 컴파일러에 지시하는 방법이 있습니다. 하지만 뮤텍스는 일반적으로이 문제를 해결하지 못합니다.