查看完整版本: [-- 线程不能销毁,求助 --]

QTCN开发网 -> Qt基础编程 -> 线程不能销毁,求助 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

mugua001 2021-09-02 19:53

线程不能销毁,求助

每次收到数据,就创建新线程,结果 客户端 断开连接,线程依然在。
若是 加上 //subThreadContainer->quit();    //subThreadContainer->exit();  监听程序直接没了,进程直接消失(WIN10)。
如何正确地销毁 临时创建的线程呢?


//---------------------------------------------------------------------------------------------------
void psw_edit_v2_server::socket_Read_Data_slot()
{
    //收到数据
    //发送线程信号emit openThreadSignal();  创建新线程处理;

emit openThreadSignal(socket001, cipherStr);//触发openThreadSlot()创建绑定线程,将数据处理任务交给线程完成;

}

void psw_edit_v2_server::openThreadSlot(QTcpSocket *dstClientTcpSocket, QString msgText)
{
    /*开启绑定一条多线程*/
    qDebug() << tr("开启子线程");
    subThreadContainer = new QThread(this);           //创建子线程(容器);
    myObjectThread = new MyWorkThreadQtEh();          //需要在线程中运行的类对象,注意不能指定父对象
    myObjectThread->moveToThread(subThreadContainer);    //将创建的对象移到线程容器中


    //connect(subThreadContainer, SIGNAL(execThreadFun()), myObjectThread, SLOT(execThreadSlot()));//启动线程中槽函数执行耗时任务;
    connect(this, &psw_edit_v2_server::execThreadFun, myObjectThread, &MyWorkThreadQtEh::execThreadSlot);

    connect(subThreadContainer, SIGNAL(finished()), myObjectThread, SLOT(deleteLater()));   //终止线程时要调用deleteLater槽函数
    connect(subThreadContainer, SIGNAL(finished()), subThreadContainer, SLOT(deleteLater()));

    connect(subThreadContainer, SIGNAL(finished()), this, SLOT(deleteLater()));    //可选操作,官方就没写这条;


    subThreadContainer ->start();

    qDebug() << "Main QThread::currentThreadId()==" << QThread::currentThreadId();
    //线程创建完成后,接着调用线程执行耗时任务;发送execThreadFun()启动子线程的信号;
    emit execThreadFun(dstClientTcpSocket, msgText);
}

20091001753 2021-09-02 20:30
当你提问的时候,如果直接贴一大段代码,其实没人会仔细去看,那就更没人来回答。

你可以尝试归纳总结问题,然后再提问。

mugua001 2021-09-02 20:54
20091001753:当你提问的时候,如果直接贴一大段代码,其实没人会仔细去看,那就更没人来回答。
你可以尝试归纳总结问题,然后再提问。 (2021-09-02 20:30) 

谢谢!

前面三行文字描述,就是问题所在。

附代码,是方便各位大神诊断。

tanyue.esec 2021-09-03 08:42
我自己的办法是,在创建线程的主线程类的析构函数中,停止子线程的工作,调用子线程的wait函数。

然后让子线程停止工作也是需要的,我之前就是没有停止工作,界面都消失了,子线程还在不停的循环

mugua001 2021-09-03 09:40
tanyue.esec:我自己的办法是,在创建线程的主线程类的析构函数中,停止子线程的工作,调用子线程的wait函数。
然后让子线程停止工作也是需要的,我之前就是没有停止工作,界面都消失了,子线程还在不停的循环 (2021-09-03 08:42)

我也试过 线程 的 wait(),但是 程序直接 一次性就退出了,而不是线程 结束。

会不会是 我用的位置不对?(我结束子线程的操作是 在主线程中进行的……应该在子线程内部进行么?)

-------------------------------------

void psw_edit_v2_server::closeThreadSlot()
{
    qDebug() << tr("触发关闭线程信号.");
    if(subThreadContainer->isRunning())
    {
        //myObjectThread->closeThread();  //关闭线程槽函数
        //subThreadContainer->quit();            //退出事件循环
        subThreadContainer->wait();            //释放线程槽函数资源
        //subThreadContainer->terminate();
    }
}



九重水 2021-09-03 10:10
关心销毁线程之前,先关心一下:
1,为什么你要临时创建线程;
2,为什么创建线程之后你又迫不及待地销毁它?

在一个程序中,线程不是越多越好,也不是随时创建和销毁就是好的。
其实,你可以开局就创建合适的线程,然后需要的时候从中分配一个线程过去,用完就回收(不是销毁)

mugua001 2021-09-03 10:52
九重水:关心销毁线程之前,先关心一下:
1,为什么你要临时创建线程;
2,为什么创建线程之后你又迫不及待地销毁它?[表情]
在一个程序中,线程不是越多越好,也不是随时创建和销毁就是好的。
....... (2021-09-03 10:10) 

谢谢!

你这倒是个不错的主意。

开始就创建一定数量的线程,排队扫描空闲的使用……

——————————————————————————————
其实我的想法很单纯:
接收到客户端请求一次,创建个线程处理,处理完之后线程就不用了(销毁);

周而复始……

tanyue.esec 2021-09-04 10:25
每个线程处理一个连接,连接并发数上来了就不行了,线程池会好一些,找找有没有合适的第三方中间件、组件库吧。

我自己用的是随主程序创建子线程,子线程一直在while循环,主界面类的析构函数中执行子线程的wait函数。

mugua001 2021-09-04 11:29
tanyue.esec:每个线程处理一个连接,连接并发数上来了就不行了,线程池会好一些,找找有没有合适的第三方中间件、组件库吧。
我自己用的是随主程序创建子线程,子线程一直在while循环,主界面类的析构函数中执行子线程的wait函数。 (2021-09-04 10:25) 

“……主界面类的析构函数中执行子线程的wait函数……”也就是只有 主界面 退出时,才能释放线程资源……

其实我的想法(可能不正确),是不停地临时 new出新线程,每次有客户端请求时就 new出的新线程处理完某个具体事务后,自己销毁(释放);等待下一次 客户端请求再 new 新线程……

fsu0413 2021-09-04 13:02
tanyue.esec:每个线程处理一个连接,连接并发数上来了就不行了,线程池会好一些,找找有没有合适的第三方中间件、组件库吧。
我自己用的是随主程序创建子线程,子线程一直在while循环,主界面类的析构函数中执行子线程的wait函数。 (2021-09-04 10:25) 

Qt自己就有线程池。。。。

mugua001 2021-09-04 23:03
感谢各位大虾的热情帮助!

我用 线程池,终于达到我想要的效果了!再次感谢大家。

路线:主线程接收来自客户端的请求,创建新线程(从池中)处置,发到主线程中进行回复。

但是我感觉还有一个问题:主线程到子线程,通过构造函数传参到子线程,若是大并发时,这个参数是不是就应该加锁呢??子线程1构造传参进到成员A,B,结果还没等线程1结束,新的子线程构造又传参来了,A,B的值被修改了……


查看完整版本: [-- 线程不能销毁,求助 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled