나는 스레딩과 pthreads와의 동기화를 다루는 과제를 수행하고있다. 예제 코드에서 주 스레드는 잘 실행되는 두 개의 다른 스레드를 생성합니다. 두 "자식"스레드가 종료 될 때까지 주 스레드는 차단됩니다. 적어도, 이것이 내가 그것을 이해하는 방법입니다. 주 스레드가 실행을 다시 시작하면 AvionicsTask
에 대한 소멸자를 호출 할 때 세그먼트 화 오류가 발생하는 것 같습니다. 솔직히, 나는 뭔가를 올바르게 초기화하지 않을 수도 있다는 것을 제외하고는 왜 그런지 전혀 모른다. 여하튼, 코드는 다음과 같다 :왜 Seg Fault가 발생합니까?
Task.h :
class Task {
protected:
/* -- NAME */
static const int MAX_NAME_LEN = 15;
char name[MAX_NAME_LEN];
/* -- IMPLEMENTATION */
pthread_t thread_id;
public:
/* -- CONSTRUCTOR/DESTRUCTOR */
Task(const char _name[]) {
std::strncpy(name, _name, MAX_NAME_LEN);
}
~Task(){}
/* -- ACCESSORS */
char * Name();
virtual void Start();
virtual void Run()= 0;
static void GracefullyExitMainThread();
};
Task.cpp :
#include "task.h"
std::vector<pthread_t> tasklist; //keep track of tasks created
void * thunkfunc(void * args) {
Task * task_instance = (Task *)args;
task_instance->Run();
return NULL;
}
void Task::Start(){
pthread_t threadmachine;
void * start_arg = NULL;
pthread_create(&threadmachine, NULL, thunkfunc, this);
tasklist.push_back(threadmachine);
}
void Task::GracefullyExitMainThread() {
void** return_value; //unused
for(int i = 0; i < tasklist.size(); i++){
pthread_join(tasklist[i], return_value);
}
}
char * Task::Name(){
return name;
}
Task_Test_step1.cpp :
#include <iostream>
using namespace std;
#include "task.h"
class RudderController : public Task {
public:
RudderController(char _name[]) : Task(_name) {}
void Run() {
cout << "Rudder Controller [" << name << "] running\n" << flush;
for (int i = 0; i < 10; i++) {
cout << name << " waiting for next sensor input\n" << flush;
usleep(1000000);
cout << name << " issueing rudder control command" << i << "\n" << flush;
usleep(10000);
}
}
};
class AvionicsTask : public Task {
public:
AvionicsTask(char _name[]) : Task(_name) {}
void Run() {
cout << "Avionics System [" << name << "] running\n" << flush;
for (int i = 0; i < 10; i++) {
cout << name << " waiting for next refresh interval\n" << flush;
usleep(700000);
cout << name << " refreshing avionics screen " << i << "\n" << flush;
usleep(12000);
}
}
};
int main(int argc, char * argv[]) {
/* -- CREATE TASKS */
RudderController task1("rudder control");
AvionicsTask task2("avionics task");
/* -- LAUNCH TASKS */
task1.Start();
task2.Start();
Task::GracefullyExitMainThread();
}
프로그램의 출력 gdb :
Starting program: /home/ben/Desktop/Part 1/test
[Thread debugging using libthread_db enabled]
[New Thread 0x7ffff707e700 (LWP 6797)]
Rudder Controller [rudder control] running
rudder control waiting for next sensor input
[New Thread 0x7ffff687d700 (LWP 6798)]
Avionics System [avionics task] running
avionics task waiting for next refresh interval
avionics task refreshing avionics screen 0
...
//more messages from the threads
...
avionics task refreshing avionics screen 9
[Thread 0x7ffff687d700 (LWP 6798) exited]
rudder control issueing rudder control command7
rudder control waiting for next sensor input
rudder control issueing rudder control command8
rudder control waiting for next sensor input
rudder control issueing rudder control command9
[Thread 0x7ffff707e700 (LWP 6797) exited]
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401ffa in AvionicsTask::~AvionicsTask (this=0xffffffffffffffc0,
__in_chrg=<optimized out>) at task_test_step1.cpp:21
21 class AvionicsTask : public Task {
이것을 디버그 모드로 빌드하고 디버거를 통해 실행할 수 있습니까? 이것은 충돌에 대한 유용한 정보를 산출합니다. AvionicsTask 소멸자의 충돌에 관한 부분은 그것이 추측일지도 모르는 것처럼 들렸습니다. –
@MultimediaMike 물론! 나는 gdb 출력을 넣는 것을 잊었다. 나는 그것을 보여주기 위해 질문을 편집 할 것이다. –
'this'포인터가 정말 잘못 보입니다 (-64 포함). 너가 그 원인을 찾았다 고 말했을거야. 그 상태에 어떻게 도달하는지 알아 내면됩니다. –