为什么会导致Seg Fault?

时间:2012-03-06 23:47:38

标签: pthreads segmentation-fault destructor

我正在处理一个处理线程和与pthreads同步的任务。在示例代码中,主线程创建了两个执行正常的线程。主线程被阻塞,直到这两个“子”线程终止。至少,这是我理解它的方式。当主线程恢复执行时,它在调用AvionicsTask的析构函数时似乎遇到了分段错误。老实说,我不知道为什么,除了我可能没有正确初始化一些东西。无论如何,代码如下:

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 {

1 个答案:

答案 0 :(得分:1)

您使用return_value的方式是错误的:

void** return_value;               
for(int i = 0; i < tasklist.size(); i++){
    pthread_join(tasklist[i], return_value); // <== return_value has an indeterminate value
                                             // who knows where pthread_join() will write to?
}

如果您对正在加入的帖子对NULL传递的内容不感兴趣(或等效线程函数返回的内容),请传入pthread_exit()

for(int i = 0; i < tasklist.size(); i++){
    pthread_join(tasklist[i], NULL);   // <== ignore what the thread returns
}

如果您确定要获取线程返回的值,请使用类似以下内容的内容:

void* return_value;               
for(int i = 0; i < tasklist.size(); i++){
    pthread_join(tasklist[i], &return_value);

    // return_value contains the data the thread returned...
}
相关问题