2017-02-06 14 views
-1

여기에 장면이 있습니다 : libev를 사용하여 간단한 멀티 스레드 서버를 작성하고 디스패처 스레드와 여러 작업자 스레드를 사용하는 memcached를 사용하는 스레드 풀 모델을 구현하려고합니다 (그러나 문제는 libev가 아닙니다. 또는 memcached).std :: queue.front()가 세그먼트 오류를 ​​일으키는 이유는 무엇입니까?

는 I (일부 불필요한 필드를 생략)

typedef struct { 
    thread_t tid; 
    std::queue<event_entry *> event_queue; //event_entry is irrelavant here 
}WorkerThread; 

그럼 클래스의 개인 정적 멤버 함수 eventHandler있다

class WorkerThreadPool 
{ 
//... 
private: 
    WorkerThread *worker_threads; //worker threads, enough space allocated 
}; 

같아서의 WorkerThread 아래 구조체 인 클래스 WorkerThreadPool 정의 WorkerThreadPool, 어느 하나의 스레드 구조 (모든 스레드가 성공적으로 만들어진) 중 하나를 액세스 할 수 있습니다.

WorkerThread *wthread = &worker_threads[0]; 
if(whtread->event_queue.empty()){ 
    std::cout << "Empty!\n"; 
}else{ 
    std::cout << "Not empty.\n"; 
    event_entry *evt = wthread->event_queue.front(); 
    std::cout << "fine.\n"; 
} 

그러나 "비어 있지 않습니다. \ n"출력 바로 다음에 "괜찮습니다. \ n"가 출력되지 않으므로 충돌이 발생했습니다.

정적 멤버 함수가 비 정적 멤버에 액세스 할 수 없기 때문에 처음에는 으로 변경했을 때 을 정적으로 변경하면 오류가으로 남아 있다고 생각했습니다. 나는 또한 공개하기 위해 worker_threads을 수정하려했지만 운이 없다.

이제 저는 정말 혼란스럽고 며칠 동안 붙어 있습니다. 아무도 나에게 도움을 줄 수 있니?

+0

당신은 읽고 그것을 쓰기 전에 뮤텍스 같은 뭔가 큐를 잠글합니까? –

+0

관련이 없어도 버퍼링 된 출력을 디버깅 도구로 사용할 때주의해야합니다. 출력 버퍼가 플러시되지 않으면 프로그램이 생각했던 곳에서 프로그램이 중단되지 않았을 가능성이 있습니다. 당신은'std :: endl'으로 그 줄 바꿈을 대체하여 출력물이 충돌 전에 화면에 출력되도록 할 수 있습니다. –

+1

[mcve] 또는 [SSCCE (Short, Self Contained, Correct Example)]로 질문을 ** 편집 ** – NathanOliver

답변

1
event_entry *evt = wthread->event_queue.front(); 

은 대기열이 비어있는 경우 문제가됩니다.

당신은 사용할 필요가 :

WorkerThread *wthread = &worker_threads[0]; 
if(whtread->event_queue.empty()) 
{ 
    std::cout << "Empty!\n"; 
} 
else 
{ 
    std::cout << "Not empty.\n"; 
    event_entry *evt = wthread->event_queue.front(); 
} 
std::cout << "fine.\n"; 
+0

안녕하세요, 귀하의 답변 주셔서 감사합니다,하지만 실제로, 그것도 "비어 있지 않습니다."출력 추락. 출력 전에 비어 있지 않은지 확인하는 것입니다. 혼란스럽지 않도록 질문을 수정하겠습니다. –