Pthread_create 在 C++ 中导致分段错误

Posted

技术标签:

【中文标题】Pthread_create 在 C++ 中导致分段错误【英文标题】:Pthread_create causing segmentation fault in C++ 【发布时间】:2014-02-21 08:12:58 【问题描述】:

我正在尝试接受一个整数值,并在程序中创建该数量的线程。奇怪的是,只能创建第一个线程。经过一些跟踪,它显示 pthread_create 是导致核心转储的行。

#include <iostream>
#include <time.h>
#include <pthread.h>
using namespace std;

class Kevin

public:
    Kevin();
    static void* Speak(void* value);
;

Kevin::Kevin()

    cout << "new instance of Kevin is created\n";


void* Kevin::Speak(void* value)

    cout << "Name: Kevin" << *((int*)value) << "\n" << "Seconds since epoch:" << "\nThread id:" << pthread_self() << endl;


int main(int argc, char *argv[])

    int threadsNumb = atoi(argv[1]);
    cout << "number of threads :" << threadsNumb <<endl;
    int status;
    int i;
    pthread_t threads[threadsNumb];
    for(i=0;i<threadsNumb;i++)
    
        cout << "what is i? " << i << endl;
        cout << &threads[i] << i << endl;
        cout << "threads" << threads[i] << endl;
        cout << "thread Numb" << threadsNumb << endl;

        pthread_create(&(threads[i]),NULL,Kevin::Speak,(void *)&i); // this line
        pthread_join(threads[i], (void **)&status);
        cout << endl;
    
    return EXIT_SUCCESS;

使用“./a.out 3”运行会得到以下输出:

number of threads :3
what is i? 0
0x7fff3600ae400
threads6296496
thread Numb3
Name: Kevin0
Seconds since epoch:
Thread id:1117690176

what is i? 1
0x7fff000000081
Segmentation fault (core dumped)

我尝试将 pthread_t threads[threadsNumb]; 的声明移动到 for 循环中,它可以运行,但它会给我所有相同的线程 id,这是不希望的。知道核心转储的原因可能是什么吗?我花了几个小时才解决这个小问题。 我也研究了一个类似的问题,但我没有重新声明任何东西:pthread_create causing segmentation fault

这是我将 pthread join 的第二个参数更改为 NULL 后得到的。

what is i? 0
0x7fffe23e12f00
threads6296496
thread Numb3
Name: Kevin0
Seconds since epoch:
Thread id:1098664256

what is i? 1
0x7fffe23e12f81
threads242525729787
thread Numb3
Name: Kevin1
Seconds since epoch:
Thread id:1098664256

what is i? 2
0x7fffe23e13002
threads47489276644304
thread Numb3
Name: Kevin2
Seconds since epoch:
Thread id:1098664256

为什么线程 id 相同?

【问题讨论】:

您不应该将&amp;i 传递给您的线程,它甚至可能在您的线程访问它之前增加。绝对是一场比赛。 @HAL 因为 OP 在pthread_create 之后直接调用pthread_join,所以它是安全的,因为这意味着程序基本上是单线程的。 @JoachimPileborg 当然这不会导致崩溃,但是这个参数传递肯定不是一个好习惯。 有什么理由不使用C++ threads?与原始 pthread API 不同,它们是类型安全的。 @McKevin Pass i。有关将参数传递给线程的更多信息,computing.llnl.gov/tutorials/pthreads/#PassingArguments 【参考方案1】:

可能的原因是您使用的是 64 位机器,其中 int 是 32 位,但指针是 64 位。这意味着您的pthread_join 调用将写入为变量status 分配的空间之外。变量i 被覆盖的可能性不大(提示您在第二个循环中打印的地址与第一个地址非常不同)。

在您的情况下,您实际上并没有从线程函数返回任何内容,您不妨将NULL 传递给pthread_join 的第二个参数。

【讨论】:

谢谢!!但是现在 pthread_self() 生成相同的线程 id,这是用来获取线程 id 的正确方法吗? computing.llnl.gov/tutorials/pthreads/man/pthread_self.txt @McKevin 它可能会为您提供相同的线程 ID,因为您的程序实际上仍然是单线程的。在pthread_create 之后直接调用pthread_join,这意味着主线程将等待创建的线程完成后再继续。如果你想让它真正成为多线程,那么在一个循环中创建线程,然后在另一个循环中调用pthread_join 在所有创建的线程上。但请注意,首先阅读 HAL 中的 cmets。此外,您确实应该进行一些错误检查(以确保线程创建成功)。 谢谢,我把创建和加入分成两个循环,现在它是多线程的。

以上是关于Pthread_create 在 C++ 中导致分段错误的主要内容,如果未能解决你的问题,请参考以下文章

linux 之 pthread_create 实现类的成员函数做参数

pthread_create() 不正确的启动例程参数传递

类成员函数作为pthread_create函数参数

C++多线程怎么实现

c++多线程同时运行两个函数该怎样编程啊?

让 C 回调调用 C++ 成员函数的最佳方法?