2010-03-26 3 views
2

O/S Thread.Sleep (10)을하지 않고도 협업/비 선점 멀티 태스킹으로 양보 또는 교착 상태를 방지하는 창의적인 아이디어가 있습니까? 일반적으로 yield 또는 sleep 호출은 스케줄러로 다시 호출하여 다른 작업을 실행합니다. 그러나 이것은 언젠가 교착 상태를 일으킬 수 있습니다.교착 상태를 방지하는 협동/비 선점 스레드?

일부 배경 :

이 응용 프로그램은 같은 업계의 다른 시스템에 비해 지금까지, 그것은 매우 빨리 속도와, 엄청난 필요가있다. 속도 기술 중 하나는 O/S 스레드의 컨텍스트 전환 비용 대신 협동/비 선점 스레드입니다.

우선 순위 및 처리 시간에 따라 작업을 호출하는 우선 순위 관리자를 상위 수준으로 설계합니다. 각 작업은 작업의 "반복"을 수행하고 우선 순위 대기열에서 차례를 다시 기다립니다.

비 선점 스레딩의 까다로운 문제는 특정 작업을 작업 도중에 중지하고 계속하기 전에 다른 작업의 다른 이벤트를 기다리고 싶을 때해야 할 일입니다.

이 경우 우리는 A와 B의 작업을 동기화해야하는 A와 B의 3 가지 작업을 수행합니다. 먼저 A가 B와 C를 시작합니다. 그러면 B가 생성되어 C가 호출됩니다. C가 yield 될 때, A는 둘 다 비활성 상태라고보고, B가 실행될 시간이지만 C의 시간은 아직 결정하지 않습니다. 이제는 B가 C를 호출하는 수익률에 머물러 있기 때문에 결코 실행할 수 없습니다.

+0

흥미로운 질문입니다. 귀하의 대답이 귀하가 사용하고있는 언어임을 나타내는 것으로 보이기 때문에이 C#으로 표시하십시오. –

답변

0

C# 언어가 스택 전체를 덮기 위해 진정한 "연속"을 지원하고 나중에 중단 된 부분을 계속 지원하는 경우에 이상적인 솔루션입니다.

이 상황이 아니라면이 상황의 작업에서 "isInterrupted"플래그를 true로 설정하고 반환하여 스택을 푸는 것이 허용됩니다.

그런 다음 스케줄러가 해당 작업에 대한 처리 시간을 다시 예약하려는 경우 isInterrupted가 표시되고 이미 수행 된 처리를 건너 뛰고 간단한 if 문을 사용하여 인터럽트 위치로 바로 이동합니다.

감사합니다. 웨인

1

아마도이 문제를 처리하는 가장 깨끗한 방법은 항복 (특정 이벤트를 기다리는 중)에서 차단하는 것으로 결정하는 스레드를 분리하는 것입니다. 따라서 비교적 쉽게 스레드에 시간을 할당 할 수 있지만 차단 된 스레드를 실행하려고하면 교착 상태가 발생하지 않습니다. 일반적으로 어떤 스레드가 다른 스레드에서 블로킹 중인지에 대한 토폴로지 정렬을 수행하려고하므로 다른 스레드에서 대기중인 스레드에 시간을 할애 할 수 있습니다. 이것은 DAG를 제공해야합니다 - 그래프의 모든 사이클은 교착 상태를 나타냅니다.

+0

좋아, 좋은 지적이야. 더 많은 정보 : 우리는 이미 그렇게합니다. 우리가 태스크에 의해 처리하는 "수익률"이라고 부르는 것은 리턴을 수행하여 스택이 스케줄러로 되돌아 간다. 즉,이 토론에서 수율과 수면이 모두 막히고 있음을 의미합니다. 이렇게 : while (! xevent) Yield(); 우리는 이미 DAG를 처리하고 있으며 다른 모든 경우를 해결합니다. 그러나 위의 질문에있는 하나, 당신이 그것을 더 자세히 연구한다면 그 방법으로는 해결되지 않습니다. B와 C 사이에는 0의 종속성이 있습니다. 단순히 동기화해야합니다. 그래서 그들은 각각 일시 중지하고 다음에 실행될 알림을 기다려야합니다. – Wayne

+0

여기서 근본적인 문제는 각 작업이 대기하는 동안 스택을 묶는 것입니다. 지저분한 해결책 중 하나는 B와 C를 각각 2 개의 작업으로 나눠서하는 것입니다. 그래서 B는 B1과 B2가됩니다. 그런 식으로 B1과 B2는 서로 상태를 앞뒤로 전환하여 실행할 수 있습니다. B1이 끝날 때 블록이 필요할 경우 B2를 비활성화 한 후에 작업을 종료 할 수 있으므로 B2가 A로 재 활성화 될 때까지 실행을 시작하지 않습니다. 그런 식으로 스택은 두 경우 모두 해제됩니다. 사랑스런 코드를 이렇게 조각내는 것은 추한 것입니다. 그러나 더 좋은 아이디어가 없다면. – Wayne

+0

어쩌면 나는 잠을 자지 못했을 지 모르지만 나는 여전히 여기에있는 문제를 아직 따르지 않고있다. 어떤 스레드가'while (! xevent) Yield();'를 가지고 있고,'xevent'를 설정할 것으로 기대하고 있습니까? 규칙을 약간 변경하면 다소 다른 가능성이 있습니다. 오버 헤드를 줄이기 위해 협업 멀티 태스킹을 사용하지만 교착 상태가 발생하는 경우에만 * 선점하는 워치 독 타이머를 사용하십시오. –