2011-04-12 5 views
1

친애하는 C++ 전문가. 문제가 생겼어. 나는 하나의 추상 클래스 base_class와 2 개의 파생 클래스 (sippeers와 dbget)를 가진 프로그램을 가지고있다. 또한 2 개의 스레드가 있습니다. 첫 번째 스레드는 사용자로부터 명령을 받고, 두 번째 스레드는이 명령을 사용합니다. 두 파생 클래스 모두 다른 명령을 나타냅니다. 그래서, 나는 어떤 종류의 스택을 만들어야 만합니다. 여기서 첫 번째 스레드의 사용자 명령을 처리하고 두 번째 스레드에서 처리하도록해야합니다. 모든 명령에 대해 하나의 스택을 만들기 위해 다형성 (polymorphism)을 사용해야합니다. 첫째, std :: list를 사용하려고했습니다. 그러나 첫 번째 문제가있었습니다. 나는 추상적 인 클래스 목록을 만들 수 없습니다. 그런 다음 boost :: ptr_list를 사용하려고 시도했지만 두 번째 문제가있었습니다. 즉, 첫 번째 스레드에서 생성 된 클래스는 프로 시저의 끝 부분에서 사라져서이를 생성했습니다. 따라서 포인터는 불법이됩니다. 질문 : 어떤 종류의 실현을 사용해야합니까? 파생 클래스의 모든 복사본을 저장해야하는 것 같습니다. 그러나 어디에서?폴리 모달 클래스의 스택

답변

1

shared_ptr<base_class>의 std :: queue는 메모리 관리에 신경 쓸 필요없이 클래스간에 스레드를 전달하는 가장 간단한 솔루션입니다. 대기열이 비어 있지 않음을 알리는 조건부 변수와 결합하여 소비자 스레드가 대기 할 수 있도록합니다.

다형성 부분에는 추가 가상 함수 (execute()?)가 있어야합니다. 따라서 소비자 스레드는 실제로 어떤 클래스를 수신하는지 인식해서는 안됩니다.

+0

해결책이 될까요? 내가 표준 : : 목록을 사용할 수 있습니다 <부스트 : : shared_ptr의를 이>, 두 번째 스레드가 같은 것을 할 수있는이 목록에 포인터를 넣을 수 첫 번째 스레드 명령 : 동안 { base_command C 형 = 명령 (commands.empty()!)를 .앞(); commands.pop_front(); } – CagoBHuK

+0

shared_ptrs (당시에는 알지 못했던)를 제외하고 이것은 우리가 사용하는 (단순화 된) 솔루션입니다. 모든 것이 필요하기 때문에 std :: queue를 사용합니다. 일부 명령 인스턴스를 제거/대체하려면 std :: list를 사용할 수 있습니다. 빈/전체 큐에서 차단하려는 경우 '조건 변수'/ 모니터/세마포어를 잊지 마십시오. – stefaanv

1

먼저 std :: list를 사용하려고했습니다. 그러나 첫 번째 문제가있었습니다. 나는 추상적 인 클래스 목록을 만들 수 없습니다.

당신은, 그러나, std::list포인터 추상 기본 클래스에, 예를 들어 만들 수 있습니다

std::list<base_class *> commands; 

는 그럼 난 부스트 :: ptr_list을 사용하려고하지만 두 번째 문제가 있었다 : 첫 번째 스레드에서 만든 클래스, 절차의 끝 dissappear, 즉를 만들었습니다. 따라서 포인터는 불법이됩니다.

첫 번째 스레드 스택에 새 명령이 생성된다는 의미입니까? 그렇게하지 마십시오 - 첫 번째 스레드는 두 번째 스레드가 명령 처리를 마친 시점을 알지 못하므로 첫 번째 스레드가 종료 시점을 정의해서는 안됩니다. 첫 번째 스레드가 new을 사용하여 객체를 할당하게하십시오.

그렇다면 사용 사례는 생산자 - 소비자 문제의 고전적인 사례처럼 들립니다. 이러한 시스템을 올바르게 구현하는 방법에 대한 영감을 얻기 위해 the Wikipedia page을 살펴보십시오. 잘못 입력하는 것은 그리 어렵지 않습니다.