2017-12-22 29 views
-1

나는 부스트 스레드를 사용하는 C++ 98 프로젝트를 가지고 있습니다.()스레드와 신호

for(int i=0;i<numCPU;++i) 
{ 
    vThreads.push_back(new boost::thread(boost::bind(&TControl::startCPU,this,i,fnp))); 
} 

및 작업자 스레드가 getWork만큼 실행 workunits를 반환 : 메인 스레드는이 같은 12 개 쓰레드를 생성

void startCPU(int id,StartFn fnp) 
{ 
    unused(id); 
    while(true) 
    { 
     WU_TYPE* pWU(getWork()); 
     if(pWU==NULL) return; 
     CALL_MEMBER_FN(pWU,fnp)(); 
    } 
} 

특정 workunits은 매우 긴 실행할 수 있습니다. 목표는 이미 스레드가 (startCPU (void)를 실행하는) 새로운 작업 단위를 시작할 수 있도록 이미 60 분 이상의 런타임을 가진 작업 단위를 죽이는 것입니다.

처음에는 신호로 처리 할 수 ​​있다고 생각했는데, 주 ​​스레드가 매분마다 신호를 올릴 수 있고 각 스레드 내부의 신호 처리기가 지연된 작업 단위에 대한 예외를 throw 할 수 있습니다. 그러나 조금 읽은 후에는 한 스레드에서 발생한 신호가 다른 스레드의 신호 처리기를 시작하지 않기 때문에 이렇게 작동하지 않는 것 같습니다. 맞습니까? 이 목표를 달성하기위한 적절한 기술은 무엇입니까?

참고 : C++ 11을 사용할 수 없으므로 소프트웨어는 이전 시스템에서 컴파일해야합니다.

+0

종료 시간이 지난 경우 -> 현재 시간 확인 -> 종료 시간 남음 ->이 변수 설정은이 스레드가 완료된 작업 단위를 표시합니다. – Detonar

+0

CALL_MEMBER_FN은 작업 단위 pWU의 멤버 함수 포인터 fnp를 실행하고 작업 단위가 완료 될 때까지 반환하지 않습니다. 목표는 fnp()를 매 순간 중단하고 죽일지를 점검하는 것입니다. – Geom

답변

0

스레드에서 현재 실행중인 코드를 지원하지 않으면 수행 할 수 없습니다. 스레드는 프로세스 컨텍스트를 공유합니다. 그들은 잠금을 획득 한 다음 컨텍스트를 손상시키고 잠금을 해제하기 전에 컨텍스트를 정상 상태로 되돌려 보내야합니다. 그렇지 않으면 프로세스 컨텍스트가 손상됩니다. 따라서 현재 실행중인 코드의 협조없이 스레드를 죽일 수는 없습니다.

협력을 통해 지원하는 모든 방법을 사용할 수 있습니다. 코드가 부스트의 interrupt 기능을 지원한다면, 그것을 사용할 수 있습니다. 코드 이 "인터럽트 지점"을 구현하여 인터럽트되었는지 확인하고 스레드를 정상적으로 종료해야합니다. 그렇지 않으면 interrupt은 아무 것도하지 않습니다. 다른 메커니즘을 지원하는 경우이를 사용하십시오. 그러나 그것은 처음부터 설계되어야합니다.

그렇지 않으면 스레드가 아닌 프로세스로 코드를 분리하십시오. 이상한 일을하지 않는 한 프로세스를 종료 할 수 있습니다 (예 : 메모리 공유).

+0

감사. 하지만 쓰레드가 죽지 않아야합니다. void startCPU()를 실행하는 스레드를 12 개만 시작합니다. startCPU()에서 많은 작업 단위가 반복적으로 실행되고 커다란 작업 단위를 삭제하려고합니다. 알고리즘에서 자주 업데이트되는 진행률 막대 객체가 이미 있는데 예외를 throw 할 수 있습니다. 그러나 알고리즘이 진행 막대가 업데이트되지 않는 루프에서 예기치 않게 많은 시간이 걸릴 수 있기 때문에 이는 좋은 해결책이 아닙니다. 따라서 신호를 통해 중단하는 것이 더 나은 해결책이 될 것이라고 생각했습니다. – Geom

+0

@Geom 거의 확실하지 않습니다. 그러나 모든 코드 신호를 안전하게 만들고 싶다면 작동 할 수 있습니다. –