我正在尝试设置一个在线程中使用的变量,如果我从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;
}
答案 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()
一起使用的线程,而不是在内部创建一些其他对象?