pthread从类访问它时,变量会在直接正常工作时丢失

时间:2012-03-30 14:04:19

标签: c++ pthreads

我正在尝试设置一个在线程中使用的变量,如果我从main函数调用pthread它可以正常工作,但是如果我从一个函数或类中的函数调用它,那么变量就会丢失然后打印垃圾,这就是我添加条件

的原因
  

if(this-> pickup< 7)

所以我最小化了代码,所以我可以在这里发布,因为它有我所说的所有例子。

以下代码的输出为:

  

按类访问:

     

你好,世界! <

     

直接访问:

     

你好,世界!,N:6<

我希望在Access中直接访问Access中的结果,我希望它输出“,N:6”,因为它毕竟是定义的。我在这里错过了什么?

我希望我很清楚,先谢谢。

(顺便说一句,我正在使用可用于Windows的pthread库) 所以这是代码:

#include <stdio.h>
#include <pthread.h>
#include <iostream>
#include <conio.h>
#include <windows.h>

class C {
public:
    int pickup;

    void *hello()
    {
        std::cout << "\nHello, world!";

        if(this->pickup < 7)
        std::cout << ", N: " << this->pickup;

        std::cout << "<" << std::endl;
        printf("HI");
        return 0;
    }

    static void *hello_helper(void *context)
    {
        return ((C *)context)->hello();
    }


    void StartThread(){
        C c;
        c.pickup = 6;

        pthread_t t;
        pthread_create(&t, NULL, &C::hello_helper, &c);
    }


};



int main () {

    C c;
    std::cout << "Access by Class: \n";
    c.StartThread();
    c.pickup = 6;
    Sleep(2000);

    std::cout << "\nAccess Directly: \n";
    pthread_t t;
    pthread_create(&t, NULL, &C::hello_helper, &c);

    _getch();
    return 0;
}

4 个答案:

答案 0 :(得分:2)

c返回时,

StartThread()被销毁,这意味着hello_helper()正在使用悬空指针导致未定义的行为。

更改为:

void StartThread(){
    C* c = new C();
    c->pickup = 6;

    pthread_t t;
    pthread_create(&t, NULL, &C::hello_helper, c);
}

请记住delete传递给hello_helper()的参数:

static void *hello_helper(void *context)
{
    C* c = static_cast<C*>(context);
    c->hello();
    delete c;
    return 0;
} 

编辑:

始终delete传递给hello_helper()的参数会阻止将堆栈分配的对象传递到hello_helper()。需要一种机制来指示hello_helper()是否负责破坏其论证。

答案 1 :(得分:1)

你在C中启动线程的StartThread()超出了范围,并且在你创建的线程有机会使用它之前被破坏。

如果您知道正在调用StartThread() on的类实例将在线程的生命周期中存在,那么您可能希望将this作为上下文而不是新的堆栈对象传递:

void StartThread() {
    pthread_t t;
    pthread_create(&t, NULL, &C::hello_helper, this);
}

答案 2 :(得分:0)

pthread_create()的调用立即返回,因此您在生成的线程确实有机会运行之前退出C::StartThread函数。因此,由C表示的c实例对象不再存在,因为它是StartThread堆栈上的自动变量。您需要确保c的生命周期存在于StartThread的堆栈之外,这通常使用动态内存或可能是静态变量等来完成。

答案 3 :(得分:0)

请注意StartThread创建一个C对象,该对象既不是来自任何参数材料(StartThread不参数),也不是来自{{1}的任何成员材料。是一个成员。你可以拥有这个:

StartThread

此外,您可能真的想要这个吗?

void StartThread(){
    pthread_t t;
    pthread_create(&t, NULL, &C::hello_helper, NULL);
}

// The code is easily moved into the thread.
static void hello_helper(void *)
{
   C c;
   c.pickup = 6;

}

即。也许你真的希望void StartThread(){ pthread_t t; pickup = 6; // use THIS object, not some new one, doh? pthread_create(&t, NULL, &C::hello_helper, (void *) this); } 启动一个与obj.StartThread()一起使用的线程,而不是在内部创建一些其他对象?