How to terminate QThread correctly?
-
I have 2 class inheriting from QThread, their run() is like:
void UdpRcv::run() { while(1){ recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL); } }
void UdpSnd::run() { while(1){ sendto(sockfd, buf, payload_len, 0, (const struct sockaddr *)&v6, sizeof(v6)); } }
I create and run several instances depends on UI setting. They run as expected.
But when I want to stop them, I get "terminate called without an active exception" randomly.Here is how I start/stop them:
void SgwWindow::debug_udp_start() { debug_udp_stop(); int cnt = ui->debug_udp_rcv->value(); for(;cnt>0;--cnt){ UdpRcv *r = new UdpRcv(this); debug_udp_rcv_list.append(r); r->start(); } cnt = ui->debug_udp_snd->value(); for(;cnt>0;--cnt){ UdpSnd *s = new UdpSnd(this); debug_udp_snd_list.append(s); s->start(); } } void SgwWindow::debug_udp_stop() { foreach(UdpRcv *r, debug_udp_rcv_list){ r->terminate(); r->wait(); delete r; } debug_udp_rcv_list.clear(); foreach (UdpSnd *s, debug_udp_snd_list) { s->terminate(); s->wait(); delete s; } debug_udp_snd_list.clear(); }
-
Because you don't terminate threads, you tell them to quit. Terminate is for those rare exceptions that you must close a thread in the middle of work without any regard for what it's doing (e.g. handling SIGSERV or something similar), it is most certainly not for regular thread closing. Anyway, since you are not using event loops you need to handle the quitting yourself.
Take a look atQThread::isInterruptionRequested()
andQThread::requestInterruption()
. It'd translate to something like:void UdpSnd::run() { while (!isInterruptionRequested()) { // Read data or w/e } } void SgwWindow::debug_udp_stop() { for (UdpRcv *r : debug_udp_rcv_list) { r->requestInterruption(); r->wait(); delete r; } }
If
sendto
orrecvfrom
block however (which is rather normal behaviour forrecvfrom
) then this doesn't work that well.On a related note, did you find
QTcpSocket
andQUdpSocket
not versatile enough for your problem? -
@Mr-Pang said in How to terminate QThread correctly?:
I have another question now,
if I do a malloc in thread, and force terminat it before freeing the memory, will it cause memory leak?Yes.