【问题标题】:Would the function pthread_cleanup_push() work with threads created with _beginthreadex()?函数 pthread_cleanup_push() 是否适用于使用 _beginthreadex() 创建的线程?
【发布时间】:2021-02-09 00:28:55
【问题描述】:

在我的项目中,我使用了第三方 DLL,它创建了一些线程,这些线程又调用了我的函数。第三方DLL中的线程是用_beginthreadex()创建的,DLL是用MSVC编译的。 我的项目是用 MINGW 编译的。

在我的函数中,我使用线程局部变量,使用 __thread 关键字,如下所示:

__thread Env* env;

Env* getEnv() {
   if(env) return env;
   return env = createNewEnv();
}

// called by the 3rd-party thread
void myFunction() {
   Env* env = getEnv();
   // do work
}

第三方库有时会杀死所有线程并随后生成新线程,对此我会收到通知。为了防止内存泄漏,我需要删除现在死线程创建的 Env 实例。问题是我不知道如何访问这些实例,因为指针是线程本地的。

我在谷歌上提出了一个使用 pthread_cleanup_push() 函数的想法,该函数存在于 MINGW 运行时中。这将理想地解决我的问题,但我不确定它是否适用于使用 _beginthreadex() 创建的线程。

有什么想法吗?是否存在另一种解决方法?

【问题讨论】:

  • 我猜pthread_cleanup_push() 技术仅适用于 pthreads 库知道的线程,但您始终可以通过在回调函数中放置 printf()(或其他)来测试该假设看看它是否被打印出来。
  • 你是对的。此外,事实证明我误解了这个函数的用法,它不适用于我的情况。现在考虑使用析构函数的 pthread_key_create()。

标签: windows multithreading pthreads thread-local


【解决方案1】:

最后,使用pthread_cleanup_push() 的想法完全错误,因为它只能在我无法访问的线程主函数中使用。它甚至不是一个真正的功能。其实是#defined的代码块,应该和pthread_cleanup_pop()一起使用。

我通过实现处理DLL_THREAD_DETACH 事件的dllmain() 解决了清理线程局部变量的问题。

关于这个话题的非常有用的讨论在这里: How to release the object in a TLS-slot at thread exit on Windows?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 2019-09-11
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多