c++dll中,在函数中创建线程,在函数执行完之后,线程也被销毁了,有什么办法可以让线程持续运行?

在dll中做一个类似监听的功能去回调java,但是在创建线程的函数执行完后,线程就销毁了,又不能通过join等待执行,有什么好办法吗?
JNIEXPORT void JNICALL Java_com_qm_scene_sdk_BaseFunction_register
(JNIEnv* env, jobject JavaObj, jstring jstr_Name, jstring jstr_Expresion) {

    //memcpy(env1, env, sizeof(JNIEnv*));
    //cout << env1 << endl;

    env->GetJavaVM(&gJavaVM);
    gJavaObj = env->NewGlobalRef(JavaObj);
    cout << gJavaVM << endl;
    cout << "Enter Register Functioin" << endl;
    string strTemperature = "temperature";
    string strName;
    jsize lLength = env->GetStringUTFLength(jstr_Name);
    char* lstr = (char*)malloc(sizeof(char) * (lLength + 1));
    env->GetStringUTFRegion(jstr_Name, 0, lLength, lstr);
    strName = lstr;
    free(lstr);
    mapEvent.insert(pair<string,string>(strName,strTemperature));

    for (auto i = mapEvent.cbegin(); i != mapEvent.cend(); ++i) {
        if (i->second.compare("temperature") == 0) {
            if (bFlag) {
                cout << "" << endl;
                bFlag = false;
                thread th(ExecuteCallback);//在这里创建了线程去执行回调
                th.detach();//线程分离,但是实际并不起作用,在函数执行结束后,线程还是被销毁了
                cout << "start thread" << endl;
                break;
            }
            else {
                continue;
            }
            //Sleep(30000);
            cout << "Register Successfully" << endl;
        }
        else if (i->second.compare("seat") == 0) {
            //DoNothing
        }
        else {
            cout << "There are no registered events" << endl;
        }
    }
    cout << "exit registe" << endl;
    cout << bFlag << endl;
    for (auto i = mapEvent.cbegin(); i != mapEvent.cend(); ++i) {
        cout << i->first << "  and  " << i->second << endl;
    }
    //Sleep(100000);//如果打开此处注释,那么线程函数会进行回调的
    return;
}

这是线程执行的方法


```c++
void ExecuteCallback() {
    int iTemerature = 20;
    cout << "Cur Temeperature: "<< iTemerature << endl;
    while (iTemerature < 51)
    {
        for (auto i = mapEvent.cbegin(); i != mapEvent.cend(); ++i) {
            cout << i->second << endl;
            if (i->second.compare("temperature") == 0) {
                cout << "i->second.compare"<< endl;
                JNIEnv* env;
                cout << "i->second.compare123" << endl;
                gJavaVM->AttachCurrentThread((void**)&env, NULL);
                cout << "i->second.compare1235" << endl;
                cout << env << endl;
                jstring jstrTemperature;
                string strTemperature = to_string(iTemerature);
                const char* charTemperature = strTemperature.c_str();
                jstrTemperature = env->NewStringUTF(charTemperature);

                jstring str_Name;
                const char* charName = (i->first).c_str();
                cout << charName << endl;
                str_Name = env->NewStringUTF(charName);
                jclass javaClass = env->GetObjectClass(gJavaObj); // instead of FindClass

                jmethodID methodId = env->GetMethodID(javaClass, "onCallback", "(Ljava/lang/String;Ljava/lang/String;)V");

                env->CallVoidMethod(gJavaObj, methodId, str_Name, jstrTemperature);

                env->ExceptionClear();

                gJavaVM->DetachCurrentThread();

            }

        }
        Sleep(3500);
        iTemerature++;

    }
    return;
}
执行的结果是没有调起来回调,就结束了,
detach分离线程并不起作用,是因为是dll的缘故吗?
在dll中能实现以上功能吗?
希望大家多提建议,在这里谢谢大家了!


可以使用 C++ 线程库中的 std::thread 类来创建线程。该类提供了 join 方法来等待线程执行完毕,并阻塞调用该方法的线程直到目标线程结束。例如:

#include 

// 创建一个 std::thread 对象来执行某个函数
std::thread t(myFunction);

// 调用 t.join() 来等待线程执行完毕
t.join();

注意,在线程结束后,std::thread 对象并不会被销毁,所以可以在需要的时候再次调用 join 方法来等待线程。

应该是线程对象被销毁导致线程没有执行回调就被结束掉了,建议你建立线程队列,持续到线程执行完毕后再从队列销毁线程,这样就能达到目的。

试试用线程池

用线程sleep同时结合条件变量进行阻塞
如有帮助,望采纳

void NewThread(MsgStruct* msg)
{
    ...
    while (true) {
        // do something

        // condition variable sync
        std::unique_lock(std::mutex) myLock(gMutex);
        if (v.empty()) {
            gConditionVariable.wait(myLock);
        }
        
        for (const auto& item : v) {
            std::cout << item << std::endl;
        }

        v.clear();
        gConditionVariable.notify_one();
    }
}


哈喽,题友你看看这篇文章的思路方法对你是否有帮助【C++:多线程中的小白(2)线程启动、结束、创建线程、join、detach】,链接:http://lihuaxi.xjx100.cn/news/214161.html

当函数执行完毕后,在函数中创建的线程通常也会被销毁。如果您想让线程持续运行,可以尝试使用 C++ 中的 std::thread 对象。

std::thread 是 C++ 标准库中的一个类,可用于创建和管理线程。该类提供了一些方法,可以用来控制线程的生命周期和行为。例如,您可以使用 std::thread::detach 方法来让线程脱离主线程,使其独立运行。

下面是一个使用 std::thread 类创建并脱离线程的简单示例代码:

#include <iostream>
#include <thread>

void thread_function()
{
  // 线程函数
  std::cout << "Hello from thread!" << std::endl;
}

void my_function()
{
  std::thread my_thread(thread_function);

  // 脱离线程
  my_thread.detach();
}

int main()
{
  my_function();
  std::cout << "Hello from main thread!" << std::endl;
  return 0;
}

在上面的代码中,我们在 my_function 函数中创建了一个 std::thread 对象,并在 thread_function 函数中执行了一些代码。最后,我们使用 std::thread::detach 方法来脱离该线程,使其独立运行。

请注意,在使用 std::thread 类时,应该遵守一些规则。例如,不要对 std::thread 对象进行复制或移动,并且应该在线程结束时显式地销毁 std::thread 对象。如果您不遵守这些规则,可能会导致线程不安全或程序崩溃。因此,在使用 std::thread 类时,建议您仔细阅读相关文档,了解如何正确使用该类。

除了使用 std::thread 类之外,还可以通过创建独立的进程来让线程持续运行。独立的进程是一个单独的执行单元,它可以脱离主线程独立运行,不会因为主线程的结束而终止。

在 C++ 中,您可以使用 std::launch::async 标志来创建独立的进程。下面是一个使用 std::launch::async 标志创建独立进程的示例代码:

#include <iostream>
#include <future>

void thread_function()
{
  // 线程函数
  std::cout << "Hello from thread!" << std::endl;
}

void my_function()
{
  // 使用 std::launch::async 标志来创建独立进程
  std::future<void> my_future = std::async(std::launch::async, thread_function);
}

int main()
{
  my_function();
  std::cout << "Hello from main thread!" << std::endl;
  return 0;
}

在上面的代码中,我们使用 std::async 函数来创建独立的进程,并使用 std::launch::async 标志来指定这个进程应该如何运行。该标志表示创建的进程应该立即启动并独立运行,直到完成任务为止。因此,在本例中,独立进程会立即启动,执行 thread_function 函数,并在完成任务后自行结束。

请注意,使用 std::launch::async 标志创建的独立进程通常是异步执行的。这意味着主线程会立即返回,而不会等待独立进程完成任务。如果您需要等待独立进程完成任务,可以使用 std::future 对象来等待该进程的结束。例如,您可以使用 std::future::get 方法来等待独立进程完成任务,如下面的代码所示:

#include <iostream>
#include <future>

void thread_function()
{
  // 线程函数
  std::cout << "Hello from thread!" << std::endl;
}

void my_function()
{
  // 使用 std::launch::async 标志来创建独立进程
  std::future<void> my_future = std::async(std::launch::async, thread_function);

  // 等待独立进程完成任务
  my_future.get();
}

int main()
{
  my_function();
  std::cout << "Hello from main thread!" << std::endl;
  return 0;
}

在上面的代码中,我们在 my_function 函数中创建了一个 std::future 对象,用于获取独立进程的结果。最后,我们调用 std::future::get 方法来等待独立进程完成任务。这样,在调用 std::future::get 方法之后,主线程会等待独立进程完成任务,并在独立进程结束时再继续执行。

通过使用 std::thread 类或创建独立进程,您可以让线程持续运行,直到完成任务为止。不过请注意,在使用线程或独立进程时,应当遵守一些最佳实践和安全指南。例如,在创建线程或独立进程时,应该注意线程安全问题,避免出现竞态条件和死锁等问题。同时,应该注意线程和独立进程的生命周期,在合适的时候销毁它们,避免内存泄漏和性能问题。

总之,让线程持续运行可以通过使用 std::thread 类或创建独立进程来实现。不过,在使用这些方法时,应该注意遵守一些规则和最佳实践,以避免线程不安全或程序崩溃等问题。

希望上述内容能够帮助您解决问题。

bool is = false;

run()
{
  is = true;
  while(is)
  {
    //线程启动代码
  }
}

stop()//创建停止
{
  is=false;
}

线程被调用时,is为true,启动线程
使用stop(),is为false,执行会停止,线程不被销毁
缺点就是线程还是在跑的

简单的一个test, 没有出现dll调用函数结束线程就结束的情况, 可能需要梳理一下你的程序的逻辑, 看看回调函数是否因为结束导致线程正常结束.

#ifndef TESTDLLTHREAD
#define TESTDLLTHREAD

#define EXPORT __declspec(dllimport)

#ifdef __cplusplus
extern "C"
{
#endif
    void executeCallback();
    void testThread();

#ifdef __cplusplus
}
#endif

#endif

#include "test150.h"
#include <chrono>
#include <iostream>
#include <thread>

void executeCallback()
{
    for (int i = 0; i != 100; ++i)
    {
        std::cout << i << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

void testThread()
{
    std::thread thrd(executeCallback);
    thrd.detach();
    std::cout << "begin" << std::endl;
}



#include "test150.h"
#include <chrono>
#include <iostream>
#include <thread>

int main()
{
    testThread();

    std::this_thread::sleep_for(std::chrono::seconds(100));

    return 0;
}

在dll中实现有点难度,并且这个和dll的设计初衷有点背道而驰啊