문제

관련 뮤텍스를 먼저 잠그지 않고 pthread_cond_timedwait를 호출 할 수있는 단점이 있습니까? Pthread_cond_signal을 호출 할 때 뮤트 잠금 장치를 사용하지 않습니까?

제 경우에는 실제로 확인할 조건이 없으며 Java Wait (Long) 및 Notify ()와 매우 유사한 동작을 원합니다.

문서에 따르면 "예측할 수없는 스케줄링 동작"이있을 수 있습니다. 그게 무슨 뜻인지 잘 모르겠습니다.

예제 프로그램은 먼저 뮤텍스를 잠그지 않고 잘 작동하는 것 같습니다.

도움이 되었습니까?

해결책

첫 번째는 괜찮지 않습니다.

그만큼 pthread_cond_timedwait() 그리고 pthread_cond_wait() 함수는 조건 변수에서 차단해야합니다. 호출 스레드 또는 정의되지 않은 동작 결과에 의해 잠긴 Mutex로 호출됩니다.

http://opengroup.org/onlinepubs/009695399/functions/pthread_cond_timedwait.html

그 이유는 구현이 웨이터 목록에 안전하게 추가하기 위해 뮤 테스가 잠겨있는 것에 의존하기를 원하기 때문입니다. 먼저 확인하지 않고 뮤텍스를 풀어주고 싶을 수도 있습니다.

두 번째는 혼란 스럽습니다.

예측 가능한 스케줄링 동작이 필요한 경우 스레드 호출에 의해 뮤트가 잠겨 있습니다. pthread_cond_signal() 또는 pthread_cond_broadcast().

http://www.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_signal.html

내 머리 꼭대기에서, 나는 당신이 잠금을 취하지 않고 신호를 보내면 스케줄러 동작을 엉망으로 만드는 특정 인종 조건이 무엇인지 잘 모르겠습니다. 따라서 정의되지 않은 스케줄러 동작이 얼마나 나쁜지 모르겠습니다. 예를 들어 방송의 경우 웨이터는 우선 순위에서 잠금을 얻지 못하지만 특정 스케줄러는 일반적으로 동작합니다). 또는 웨이터가 "잃어버린"일 수 있습니다.

그러나 일반적으로 조건 변수를 사용하면 신호가 아닌 조건 (적어도 플래그)과 신호를 설정하려고하며이를 위해서는 뮤트를 가져 가야합니다. 그렇지 않으면 다른 스레드 호출 대기 ()와 동시에 발생한다면 Wait () 또는 신호 ()가이기는 지에 따라 완전히 다른 동작이 발생하기 때문입니다. 당신이 관심을 갖는 신호가 이미 일어 났음에도 불구하고 풀 타임 아웃을 기다리십시오. 그것은 조건 변수 사용자가 원하는 것이 거의 없지만 괜찮을 수도 있습니다. 아마도 이것은 "예측할 수없는 스케줄러 동작"이 문서가 의미하는 바일 것입니다. 갑자기 타임 슬라이스가 프로그램의 동작에 중요 해집니다.

btw, Java에서는 () 또는 notifyall ()을 알리려면 잠금 장치가 있어야합니다.

이 방법은이 객체의 모니터의 소유자 인 스레드에 의해서만 호출되어야합니다.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/object.html#notify ()

java 동기화 된 {/}/wait/notifty/notifyall 동작은 pthread_mutex_lock/pthread_mutex_unlock/pthread_cond_wait/pthread_cond_signal/pthread_cond_broadcast와 유사합니다.

다른 팁

Butenhof의 우수한 "Posix Threads를 사용한 프로그래밍"은 3.3.3 장의 끝 에서이 권리에 대해 설명합니다.

기본적으로, 뮤 테스를 잠그지 않고 condvar에 신호를 보내는 것은 잠재적인 성능 최적화 : 신호 스레드에 Mutex가 잠겨 있으면 Condvar에서 깨어 난 스레드는 신호 스레드가 대기 스레드가 사용할 데이터를 수정하지 않더라도 신호 스레드가 잠겨 있다는 MUTEX를 즉시 차단해야합니다.

"예측할 수없는 스케줄러 동작"이 언급 된 이유는 Condvar에서 대기하는 우선 순위가 높은 스레드가있는 경우 (다른 스레드가 높은 우선 순위 스레드를 신호하고 깨우려고하는 경우) 다른 저급 스레드가 와서 잠글 수 있기 때문입니다. Condvar가 신호를 보내고 우선 순위가 높은 스레드가 깨어날 때 Mutx는 Mutx를 방출하기 위해 우선 순위가 낮은 스레드를 기다려야합니다. 신호 전달이있는 동안 Mutx가 잠겨 있으면 우선 순위가 낮은 스레드 전에 Mutx에서 고가의 스레드가 예약됩니다. 기본적으로 당신은 높은 우선 순위 스레드를 "깨우면"스케줄러가 되 자마자 깨어날 것임을 알고 있습니다. 허용합니다 (물론 우선 순위가 높은 스레드를 알리기 전에 뮤텍스를 기다려야 할 수도 있지만 다른 문제입니다).

조건부 변수를 대기하는 요점은 원자 적 대기를 입력하고 잠금을 해제하십시오. 즉, 다른 스레드가 보호 상태를 수정하도록 허용 한 다음 다시 상태 변경에 대한 알림을 원자 적으로 받고 잠금을 얻습니다. 당신이 설명하는 것은 파이프, 소켓, 신호 또는 아마도 가장 적합한 다른 많은 방법으로 수행 할 수 있습니다. 세마포.

나는 이것이 작동해야한다고 생각합니다 (테스트되지 않은 코드 참고) :

// initialize a semaphore
sem_t sem;
sem_init(&sem,
    0, // not shared
    0  // initial value of 0
    );


// thread A
struct timespec tm;
struct timeb    tp;

const long sec      = msecs / 1000;
const long millisec = msecs % 1000;

ftime(&tp);
tp.time += sec;
tp.millitm += millisec;
if(tp.millitm > 999) {
    tp.millitm -= 1000;
    tp.time++;
}
tm.tv_sec  = tp.time;
tm.tv_nsec = tp.millitm * 1000000;

// wait until timeout or woken up
errno = 0;
while((sem_timedwait(&sem, &tm)) == -1 && errno == EINTR) {
    continue;
}

return errno == ETIMEDOUT; // returns true if a timeout occured


// thread B
sem_post(&sem); // wake up Thread A early

가능할 때마다 조건은 뮤텍스 외부에 신호를 보내야합니다. 뮤 테스는 동시 프로그래밍에서 필요한 악입니다. 그들의 사용은 여러 프로세서를 사용하여 얻을 수있는 최대 성능 시스템을 강탈하는 경합으로 이어집니다.

뮤텍스의 목적은 프로그램의 일부 공유 변수에 대한 액세스를 보장하여 원자 적으로 행동하는 것입니다. 신호 조작이 뮤트 내부에서 수행되면, 수백 개의 관련없는 기계 사이클을 뮤트에 포함시켜 공유 데이터를 보호하는 것과 아무 관련이 없습니다. 잠재적으로, 그것은 사용자 공간에서 커널로 전화를 걸 수 있습니다.

표준의 "예측 가능한 스케줄러 동작"에 대한 메모는 완전히 가짜입니다.

기계가 예측 가능한 잘 정의 된 순서로 명령문을 실행하기를 원할 때,이 도구는 단일 실행 스레드 내에서 문의 시퀀싱입니다. S1 ; S2. 성명 S1 전에 "예약"입니다 S2.

우리는 일부 조치가 독립적이고 스케줄링 순서가 중요하지 않다는 것을 알면 스레드를 사용하며 실시간 이벤트에 대한 적절한 응답이나 여러 프로세서에서 컴퓨팅과 같이 실현해야 할 성능 이점이 있습니다.

여러 스레드에서 순서를 예약하는 경우가 중요 해지면 이는 불리는 개념에 속합니다. 우선 순위. 우선 순위는 N 진술 중 하나가 잠재적으로 실행될 수있는 경우에 발생하는 일을 가장 먼저 해결합니다. 멀티 스레딩에서 주문하기위한 또 다른 도구는 대기입니다. 이벤트는 하나 이상의 스레드로 큐에 배치되며 단일 서비스 스레드는 큐 순서의 이벤트를 처리합니다.

결론은 배치입니다 pthread_cond_broadcast 실행 순서를 제어하기위한 적절한 도구가 아닙니다. 프로그램이 갑자기 모든 플랫폼에서 정확히 동일하고 재현 가능한 동작을 가지고 있다는 점에서 실행 명령을 예측할 수있는 것은 아닙니다.

"예측할 수없는 스케줄링 행동"은 바로 그 의미입니다. 당신은 무슨 일이 일어날 지 모른다. 구현도 마찬가지입니다. 예상대로 작동 할 수 있습니다. 앱이 충돌 할 수 있습니다. 몇 년 동안 잘 작동하면 레이스 조건으로 인해 앱이 원숭이가됩니다. 교착 상태가 될 수 있습니다.

기본적으로 어떤 문서가 문서가 당신에게 말하는 것을하지 않으면 정의되지 않은/예측되지 않은 캔디가 일어날 수있는 경우, 더 잘하는 것이 좋습니다. 그렇지 않으면 물건이 당신의 얼굴에 날아갈 수 있습니다. (그리고 코드를 제작에 넣을 때까지 폭발하지 않을 것입니다.

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