c ++范围和windows线程线程

我有一个定义了套接字的对象,在调用析构函数之前,套接字不会关闭或关闭。然后在实例化该对象的类中,我有一个线程执行在套接字上操作的方法之一。

我能让线程工作的唯一方法是让它像这样定义:

static DWORD WINAPI writePoints(void* param)      
{
    resume
    Dac *dac = (Dac*)param;
    //...
    dac->com->write_data(dac->d,BUF_PTS,pr);
    //...
}

从同一个类创建的线程

write_thread = CreateThread(NULL, 0, writePoints,(void*)this, 0, &dwrite_thread);

但是当涉及到运行在套接字上运行的代码时,它根本不起作用。我反而得到一个错误,说套接字不是套接字。但它在一个线程之外工作就好了。设置断点后,我看到 this 为null导致我相信它的范围问题。

我该如何解决这个错误?

on an interesting side note another thread that operates on the socket works fine and doesnt seem to loose the value of this

另一个工作线程就是这样定义的

static DWORD WINAPI ping_loop(void* param)
{
    Dac *dac = (Dac*)param;

    if (dac->com->connected())
        while (dac->com->dac_ping() == 0)
            Sleep(980);

    ExitThread(1);
    return 1;
}

主要区别似乎是 ping_loop 没有传递任何参数

0
额外 编辑
意见: 1

3 答案

猜猜你没有在Dac析构函数中等待,直到线程终止。如果main函数简短而且足够简单,那么很可能你的应用程序用完了主函数并调用了Dac类的析构函数,但是Dac创建的线程仍在运行。

在析构函数中使用 WaitForSingleObject ,等待线程终止,然后关闭套接字。

1
额外
不,我在析构函数中调用了TerminateThread
额外 作者 fotg,
通常说调用TerminateThread不是终止线程的荣耀方法。当线程获取某些内容但强制终止而不释放它时,执行此操作可能会导致资源泄漏。无论如何,只要确保在线程终止后关闭套接字,它看起来就好了。
额外 作者 0902horn,

您正在从 Dac 类的成员函数调用CreateThread。如果不是那个本身就是一个错误。

您是否验证了 Dac 对象的生命周期?传递给 CreateThread 的任何数据 lpParameter 必须比线程更长久。

0
额外
您是否使用 Dac * mydac = new Dac(); 在堆上创建Dac
额外 作者 parapura rajkumar,
这显然不允许我在评论中格式化代码
额外 作者 fotg,
线程在Dac对象的析构函数中终止,所以我认为这意味着Dac对象将比线程更长。我从成员函数调用CreateThread
额外 作者 fotg,
没有在主要和它的Dac dac创建Dac;
额外 作者 fotg,

我解决了这个问题, void *LPVOID 之间存在差异, LPVOID 似乎维护 this 变量

0
额外
不,LPVOID被定义为 typedef void * LPVOID; ,所以它完全相同。我猜它是偶然的。
额外 作者 rodrigo,
可能你没有正确的锁定和/或同步使用线程。这具有非确定性行为,因此奇怪的事情和随机崩溃是预期的结果。
额外 作者 rodrigo,
那么这个问题实际上很奇怪,很难追查。我有一个for循环执行1000次迭代,使用void *它会一直通过大约100次迭代然后这个指针我通过一个void指针突然变成NULL,但是把它改成LPVOID,这是在整个文档中使用,没有这个问题。如果它是同一类型的类型,那么就会发生一些非常奇怪的事情。
额外 作者 fotg,