2010-12-09 2 views
1

구현에있어 POSIX를 염두에두고 있습니다 만,이 질문은 아키텍처에 관한 것입니다.영구 다중 스레드를 설정하고 관리하는 방법은 무엇입니까?

몇 가지 주요 작업이있는 업데이트 루프부터 시작합니다. 이러한 작업을 공통 메모리 액세스 요구 사항이있는 4 ~ 5 가지 주요 작업으로 그룹화 할 수 있습니다. 이러한 작업을 자신의 스레드로 나누어 "업데이트"의 한주기를 완료하고 다음 프레임까지 잠자기하는 것이 좋습니다.

하지만 동기화하는 방법은 무엇입니까? 각주기의 시작시에 네 개 또는 다섯 개의 쓰레드를 분리하면, 한 번 실행하여 죽게 한 다음 각 패스에서 다른 4-5 개의 쓰레드를 분리하십시오. 그것은 비싸게 들린다.

이러한 스레드를 한 번 생성하면 동기화 된 호출이 깨어날 때까지 잠자기 상태가됩니다.

현명한 접근입니까? 나는 아이디어만으로 어떤 종류의 구현에 대한 응답을 받아 들일 수 있습니다.

편집 : 지금까지 응답에 따라, 나는 추가 할 :

  • 동시성
  • 을 원하는 이들 작업자 스레드가 매우 짧은 기간 <은 250ms
  • 작업에서 실행하기위한 것입니다 각 스레드에 의해 수행됩니다 항상 동일합니다
  • 난 4-5 스레드를 고려 중이 야, 20 하드 제한되는.

답변

1

항상 모든 사이클을 수행하는 데 동일한 작업이 있고 다음주기가 시작되기 전에 모든 작업이 완료 될 때까지 기다려야하는 경우 올바른 해결 방법에 대해 생각하고 있습니다.

"프레임 세마포어 시작", "프레임 세마포어 끝"및 "프레임 종료 이벤트"와 같은 일부 동기화 개체가 필요합니다.

while true: 
    set "worker count" to n 
    increment "start of frame semaphore" by n 
    wait on "end of frame event" 
    increment "end of frame semaphore" by n 

이 잘 작동합니다 :

while true: 
    wait on "start of frame semaphore" 
    <do work> 
    enter lock 
    decrement "worker count" 
    if "worker count" = 0 then set "end of frame event" 
    release lock 
    wait on "end of frame semaphore" 

당신은 다음 컨트롤러 스레드 실행을 할 수 있습니다 : n을 독립적 인 작업을 각 프레임이있는 경우,이 (의사)과 같이 루프와, n 개의 스레드를 시작합니다 작은 n을 위해. 각주기를 완료하는 데 필요한 작업 수가 많아지면 스레드를 사용하여 시스템을 압도하지 않도록 작업 대기열과 결합 된 스레드 풀을 사용하는 것이 좋습니다. 그러나이 솔루션에는 복잡성이 더해지고 스레딩의 복잡성이 적입니다.

+0

안녕하세요. 나는 이것이 나의 필요에 대한 합리적인 접근법처럼 들린다 고 생각한다. 나는 이것에 12 스레드 지나서가는 자신을 보지 못한다. 특히 N이 너무 커지면 스레드를 통합 할 수있는 옵션이 있기 때문에 특히 그렇습니다. 이 구현에서 작업자 스레드는 항상 활성이지만 세마포 만이 코드를 래핑 할 것인가? 또는 posix 라이브러리가 스레드를 일시 중지 (잠자기) 한 다음 세마포어에서 스레드를 다시 활성화하겠습니까? 컨트롤러 루프는 단순히 세마포어의 상태를 설정합니다. 맞습니까? – bitcruncher

+0

"활성"이라는 것이 무슨 뜻인지 모르겠습니다. 세마포어를 기다리면 세마포어가 증가 할 때까지 스레드가 잠자기 상태가됩니다. 스레드는 세마포어가 해제 될 때까지 CPU 또는 스케줄러 리소스를 소비해서는 안됩니다. 컨트롤러 스레드는 세마포어의 상태를 설정하기위한 것입니다. 약간의 복잡성으로 인해 스레드는 제거 될 수 있지만 복잡성은 적이며 대개 스레드가 수행 할 다른 것이 있습니다. :) –

1

아마도 작업 대기열을 사용하는 것이 가장 좋습니다.

작업 대기열은 작업을 대기중인 스레드로 볼 수 있습니다. 한 번에 많은 정보가 전송되면 FIFO 순서로 실행됩니다.

그런 식으로 4-5 개의 스레드를 유지 관리하고 각 스레드는 각 작업에 대해 새 스레드를 분리하지 않고도 사용자가 피드 작업을 실행합니다.

유일한 문제는 C에서 많은 작업 대기열을 알지 못한다는 것입니다. Apple은 Grand Central Dispatch를 사용합니다. FreeBSD도이 기능을 구현했습니다. 그것들을 제외하고 나는 다른 것을 모른다. (비록 열심히 보지 못했습니다.)

2

스레드가 수행하는 작업의 세분성에 따라 다릅니다. 스레드가 오래 걸리는 작업 (예 : 2 번째 또는 그 이상)을 수행하는 경우 스레드 작성 및 삭제 비용은 스레드가 수행하는 작업에 비해 무시할 수 있으므로 간단하게 유지하고 필요에 따라 스레드를 만드는 것이 좋습니다.

반대로 매우 짧은 작업 (예 : 10-100 밀리 초 정도)이있는 경우 많은 스레드를 만들고 파괴하는 데 드는 비용에 주목해야합니다. 이 경우 스레드를 한 번만 생성하고 작업이 도착할 때까지 잠자기 상태로 만들어야합니다. condition variable (예 : pthread_cond_t)을 사용하는 것이 좋습니다. 스레드는 조건 변수를 기다리고 작업이 도착하면 조건 변수를 알립니다.

+0

+1. 나는 당신의 대답을 받아 들였지만 존 (John)은 나의 필요에 더 가까운 구현을 제안했다. – bitcruncher

0

아이디어를 스레드 풀이라고합니다. WinAPI, Intel TBB 및 Visual Studio ConcRT에서 볼 수 있습니다. POSIX에 대해 많이 알지 못하므로 도움이되지 않지만 훌륭한 게시판이있는 경우 탁월한 확장 성을 갖춘 훌륭한 구조입니다. 헤어지자.

그러나 작업을 수행하는 데 필요한 시간은 그리 평범하지 않습니다.5 개의 작업이 있고 성능 문제가 너무 많아 여러 스레드가 핵심이라면 스레드를 만드는 것은 거의 무시할 수없는 문제입니다.

+0

감사합니다. 경고에 감사드립니다. 이 경우에도 너무 오래 걸리기 때문에 작업을 해 내지는 못합니다. 나는 동시성의 주요 후보자 인 다른 영역을 구분하려고 노력 중이다. – bitcruncher

+0

@bitcruncher : 동시성은 단 하나의 목표, 즉 성능을 가지고 있습니다. 성능이 필요하지 않으면 동시성이 필요하지 않습니다. – Puppy

+0

물론 그렇습니다. 나는 내 구현에서이 시점에서 기존의 모 놀리 식 작업을 리팩터링하려고 시도하지 않는다고 말하려고한다. 나는 유사한 메모리 공간을 공유하고 가능한 한 빨리 실행해야 할 미래의 작업을위한 토대를 마련하고 있습니다. – bitcruncher

관련 문제