首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这会导致Seg故障?

为什么这会导致Seg故障?
EN

Stack Overflow用户
提问于 2012-03-07 07:47:38
回答 1查看 183关注 0票数 1

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

Task.h:

代码语言:javascript
复制
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:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
#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的程序输出:

代码语言:javascript
复制
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 {
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-07 09:44:06

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

代码语言:javascript
复制
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?
}

如果你不关心你加入的线程传递给pthread_exit()的是什么(或者等价的线程函数返回了什么),那么就传入NULL

代码语言:javascript
复制
for(int i = 0; i < tasklist.size(); i++){
    pthread_join(tasklist[i], NULL);   // <== ignore what the thread returns
}

如果您决定要获取线程返回的值,请使用如下所示的内容:

代码语言:javascript
复制
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...
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9593730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档