2010-05-25 3 views
0

두 개의 스레드가 있어야합니다. 모두 thread1 및 thread2 것을이 같은를 작성하는 가장 좋은 방법은 무엇멀티 스레딩하는 방법?

for (;;) { 
    Notify thread1 I am idle. 
    Wait for thread1 to be ready. // i.e. via 1st condition variable. 
    Notify thread1 I am exclusive. 
    Do some work while thread1 is blocked. 
    Notify thread1 I am busy. // i.e. via 2nd condition variable. 
    Do some work in parallel with thread1. 
} 

:

void waitForThread2() { 
    if (thread2 is not idle) { 
    return; 
    } 
    notifyThread2IamReady(); // i.e. via 1st condition variable 
    Wait for thread2 to finish exclusive access. // i.e. via 2nd condition variable. 
} 

두 번째 thread2는 다음 의사 루프에 영원히 : 첫 번째 thread1 때때로 다음과 같은 의사 함수를 호출 여러 개의 코어가있는 시스템에서 가능한 한 많이 사용합니다. 하나의 스레드에서 알림과 다른 스레드에서 감지 사이의 긴 지연을 피하고 싶습니다. pthread 조건 변수를 사용하여 시도했지만 thread2 사이의 지연을 'notify thread1 I 'm busy'라고하고 thear2IsExclusive()의 waitForThread2() 루프가 거의 1 초 지연 될 수 있습니다. 그런 다음 휘발성 sig_atomic_t 공유 변수를 사용하여 동일하게 제어하려고 시도했지만 잘못되었으므로 제대로 수행하지 않아야합니다.

+4

당신은 이미 생각한 해결책을 구현할 것을 요구하기보다는 실제로 해결하려고하는 문제를 사람들에게 이야기하는 것이 더 낫습니다. –

+0

당신의 의사 코드는별로 의미가 없습니다. 바쁜 다른 스레드에게 어떻게 알리나요? 그 이유는 무엇입니까?또한 여기 스레드에 집중하고 있습니다. 일반적으로 데이터를 동기화해야합니다. 어떤 데이터를 동기화하고 있으며, 동시에 작업을 병행하고 있습니까? – WhirlWind

+0

당신이 무언가를하기 위해 초심을 돌리고 있다면 뭔가 잘못하고있는 것입니다. 게다가 할 수있는 일은 "다른 스레드에게 알린다"가 아니라 데이터 구조를 잠그는 것입니다. 후자는 비례하지 않습니다. –

답변

1

랑데뷰를하려고하는 것처럼 보입니다. Ada의 용어).

두 번째 스레드가 앉아서 첫 번째 스레드가 호출하기를 기다리고있다가 첫 번째 스레드가 대기하는 동안 즉시 작동하고 첫 번째 스레드가 완료된 후 더 많은 작업을 수행합니다.

첫 번째 스레드가 두 번째 스레드를 "호출"합니다. 두 번째 스레드를 호출 할 수없는 경우 즉시 시간 초과가 발생합니다.

에이다는

세 개의 세마포어로 구현 될 수있다 ... 직접 언어이 지원하지만 에이다에 포팅하는 것은 옵션이 아니다 가정. 세마포어 1은 스레드 1이 랑데뷰 할 준비가되었음을 나타냅니다. 세마포어 2는 스레드 2가 랑데뷰 할 준비가되었음을 나타냅니다. 세마포 3은 랑데부가 완료되었음을 나타냅니다.

스레드 1 : 세마포어 1을 기본값으로 사용합니다.

if Semaphore 2.acquire(timeout = 0) is successful # Thread 2 is ready 
    Semaphore 1.release() # Indicate I am ready 
    Semaphore 3.acquire() # Wait until the rendevous is complete. 
    Semaphore 3.release() 
    Semaphore 1.acquire() # Indicate I am not ready 
    Semaphore 2.release() # I am no longer using thread 2. 

Do concurrent work 

스레드 2 : 세마포어 2를 기본값으로 사용합니다.

Loop forever 
    Semaphore 3.acquire() # Indicate Rendevous is not complete. 
    Semaphore_2.release() # Indicate I am ready 
    Semaphore_1.acquire() # Wait for Thread 1 to be ready 
    Joint processing 
    Semaphore 1.release() # I am no longer using thread 1. 
    Semaphore 3.release() # Rendevous is complete. 
    Semaphore 2.acquire() # I am not ready 

Post-processing 

참고 : 처음부터 작성되었으며 테스트되지 않았습니다. 내가 시작했을 때 생각했던 것보다 훨씬 복잡해 보입니다. 내가 놓친 게 있니?

+0

뮤텍스 잠금이있는 조건 변수를 사용하는 것보다 세마포가 더 효율적입니까? – WilliamKF

+0

코드 줄에서 더 효율적입니까? 던노. 런타임에보다 효율적입니까? 다른 모든 간접비와 비교할 때 그 차이를 알 수 있을지 의심 스럽습니다. 코드에서 최적화 할 곳이 많지 않으면 매우 놀랄 것입니다. – Oddthinking

3

일부 조건이 발생할 때까지 기다리는 동안 스레드가 유휴 상태 인 "while"루프가 아니라 시그널링을 위해 세마포어를 사용해야하는 것처럼 보입니다. 유휴 루프가 좋지 않습니다.

+0

유휴 루프는 실제로 아이디어를 설명하는 것이지 실제로 그렇게 구현되지는 않았습니다. 나는 그들이 주요 질문에서주의를 산만하게하고 있었기 때문에 질문에서 삭제했다. 현재, 그것들은 타임 아웃없이 조건 변수로 구현됩니다. – WilliamKF

1

스레드가 "바쁘다"또는 "바쁘지 않다"라고 말하면 스레드가 작동중인 데이터 개체를 생각해보십시오.

두 스레드가 동시에 변경하려고하는 일부 데이터 (예 : 카운터)가 있으면 거기에 뮤텍스가 필요하다는 의미입니다.

스레드가 다른 스레드가 기다리고있는 공유 데이터 상태를 변경하면 상태 변수에이를 알리기 위해 신호를 보냅니다. 예를 들어 프로듀서 스레드가 대기열에 데이터를 추가하면 소비자가 대기 할 수있는 "dataAvailable"조건을 알릴 수 있습니다.

+0

그 것이 문제의 핵심이라고 생각합니다. – WhirlWind

관련 문제