2011-08-04 4 views
1

일부 작업 (UI 루프 등)을 수행하는 기본 스레드가있는 응용 프로그램에서 작업하고 있지만, 다운로드 할 수있는 업데이트가 있는지 주기적으로 테스트합니다. 또한 주 스레드가 보조 스레드에 업데이트 검사를 강제로 요청하고 보조 스레드가 주 스레드에 업데이트 다운로드 확인을 요청할 수있는 가능성을 원합니다.멀티 스레딩을 사용하여 소프트웨어의 업데이트를 정기적으로 확인하고 강제로 업데이트를 확인합니다.

실생활에서 IPC와 멀티 스레딩에 대한 많은 경험이 없으므로 어떻게 설계해야하는지 잘 모르겠습니다. 필자는 결국이 작업을 Windows와 POSIX 모두에서하고 싶습니다. 그러나 지금은 POSIX에 집중하겠습니다. 여기 내 생각은 지금까지의 :

보조 스레드의 의사 :

repeat forever: 
    check_for_updates() 

    if (are_any_updates()) { 
    put the list of available updates on some message queue 
    send signal SIGUSER1 to main thread 
    wait for response from that message queue 
    if (response is positive) download_updates() 
    } 
    unblock signal SIGUSER1 on secondary thread 
    Sleep(one hour) 
    block signal SIGUSER1 
    if (any_signal_was_received_while_sleeping) 
    any_signal_was_received_while_sleeping := false 
    Sleep(one more hour) 
보조 스레드에

SIGUSER1 핸들러 (주 스레드가 업데이트를 확인하기 위해 우리를 요청했습니다) : 기본적으로

block signal SIGUSER1 (making sure we don't get signal in signal) 
    any_signal_was_received_while_sleeping := true 
    check_for_updates() 
    ... 
    unblock signal SIGUSER1 

, 메인 스레드가 사용하는 보조 스레드가 SIGUSER1을 사용하여 주 스레드가 사용 가능한 업데이트의 메시지 큐를 조사하고 다운로드해야하는지 여부를 확인하도록 요청하는 동안 SIGUSER1은 보조 스레드에 업데이트 확인을 강제로 요청합니다.

좋은 디자인인지, 제대로 작동하는지 확실하지 않습니다. 내 문제 중 하나는 SIGUSER1을 주 스레드에서 처리하는 것과 관련이 있습니다. 그 이유는 꽤 큰 응용 프로그램이기 때문에 차단하고 차단 해제 할시기가 언제인지 잘 모르겠습니다 (메시지 루프의 어딘가에 있어야한다고 가정합니다) .

Windows에서 IPC 기능 (신호 대신 RPC 일 수 있음)을 사용해야하는 조언을 비롯하여 모든 의견을 환영합니다. 스레드를 사용하면 메시지 대기열을 완전히 제거 할 수 있지만 대신 프로세스를 사용하는 것이 좋습니다. Windows에서 쓰레드를 사용 하겠지만, 아직 POSIX에 대해서는 잘 모르겠습니다.

+0

나는 세마포어와 시간 대기가 충분하다고 생각했을 것이다. 메인 쓰레드는 세마포어를 업데이트하기를 원할 때마다 세마포어를 게시하고, 세마포어는 세마포어에서 한시간 대기를하는 루프에 앉아있다. 그런 다음 업데이트를 확인하십시오. 메인 쓰레드는 메시지 큐를 서비스한다. 신호보다 덜 휴대 가능하지만 신호에 대해 생각할 필요가 없습니다. –

+0

@SteveJessop : POSIX/SysV 세마포어가 시간 초과를했는지 알지 못했습니다. 감사합니다. 그렇지 않더라도 pthread의 조건 변수 인 '시간 초과 대기'를 계속 사용할 수 있습니다. –

답변

1

boost::thread을 사용하여 문제를 해결하는 것이 좋습니다. posix를 직접 사용하는 것보다 훨씬 이해하기 쉽고 크로스 플랫폼입니다. 시간을 내서 더 나은 도구를 사용하면 결국 많은 노력을 덜 수 있습니다.

특히 나는 condition variable이 간단한 상호 작용을 용이하게한다는 것을 알게 될 것이라고 생각합니다.

편집 :
뮤텍스와 조건 변수를 올바르게 사용하면 거의 모든 작업을 수행 할 수 있습니다. 조언의 또 다른 부분은 encapsulate your threads inside class objects입니다. 이를 통해 스레드와 해당 데이터에서 작동하는 함수를 작성할 수 있습니다. 귀하의 경우에는 주 스레드가 requestUpdateConfirmation()과 같은 메서드를 가질 수 있습니다.이 호출 스레드를 차단하고 호출자를 해제하기 전에 주 스레드가 요청을 처리하기를 기다릴 수 있습니다.

+0

흥미 롭습니다. Boost.Thread의 조건 변수를 시간 초과 대기로 사용하지 않았습니다. 그것은 좋은 생각이지만, 나는 여전히 주 스레드에서 다운로드 권한을 요청하고자하는 보조 스레드의 문제가 있습니다.주 스레드가 다른 작업 (UI 메시지 루프)을 수행하고 있기 때문에 조건 변수를 사용할 수 없습니다. 그러나 메인 스레드가 어떻게 작동하는지 더 알지 못하면 많은 조언을 드릴 수는 없습니다. 나는 독창적 인 개발자가 아니기 때문에 신호 나 다른 형태의 커뮤니케이션을 받아들이는 정확한 장소를 찾는데 어려움을 겪고 있습니다. –

+0

보조 스레드가 다운로드 확인 대기를 차단할 수 있다고 가정하면 질문을 전달하고 주 스레드의 상태를 기다릴 수 있습니다. 메인 쓰레드가 돌아올 때 (어떤 시점에서), 질문을 확인하고, 응답을 작성한 다음, 계속 진행하기 위해 보조 쓰레드에 신호를 보냅니다. 그러면 보조 스레드가 응답을 받고 업데이트를 다운로드합니다. – radman

관련 문제