Delete thread with blocking function Topic is solved
Delete thread with blocking function
I currently have a function to delete and clean up all my threads when the application is closed (i'm using 3 wxThreads). Unfortunately one of the threads uses a blocking function call for incoming TCP/IP communication. The function will not return until communication is established, so in the case of no incoming connections, the wxThread will never be destroyed (as the while(TestDestroy()) condition will never be met). The thread never enters its destructor, and I'm unable to terminate the application correctly.
Is there a way to deal with this case in wxWidgets, or should I find a way to terminate the blocking function (it's from an external library - libmodbus, modbus_tcp_pi_accept() function). I was considering using the Kill() function to terminate the thread, but apparently its not safe.
Edit: the Kill() function doesn't help either.
Regards,
Ksawery
Is there a way to deal with this case in wxWidgets, or should I find a way to terminate the blocking function (it's from an external library - libmodbus, modbus_tcp_pi_accept() function). I was considering using the Kill() function to terminate the thread, but apparently its not safe.
Edit: the Kill() function doesn't help either.
Regards,
Ksawery
Re: Delete thread with blocking function
Can you set the length of the timeout? If not, Kill() is the only option. The main problem with this is that it can leak memory. But if happens only at app termination, that shouldn't be a problem.I was considering using the Kill() function to terminate the thread, but apparently its not safe.
Why not?Edit: the Kill() function doesn't help either.
Use the source, Luke!
Re: Delete thread with blocking function
I use the following code to terminate the thread:
The application gets stuck in the while(1) loop, since the thread destructor is never called:
Should I delete the pointer manually after using Kill()?
Regards,
Ksawery
Code: Select all
//Delete TCP/IP thread
{
wxCriticalSectionLocker enter(mbThreadCS);
if (mbThreadTCP)
{
if (mbThreadTCP->Kill() != wxTHREAD_NO_ERROR)
wxLogError("Can't delete the thread!");
}
}
while (1)
{
{
wxCriticalSectionLocker enter(mbThreadCS);
if (!mbThreadTCP) break;
}
wxThread::This()->Sleep(1);
}
Code: Select all
cThreadTCP::~cThreadTCP()
{
close(socket);
free(tcpQuery);
wxCriticalSectionLocker enter(mbGateway->mbThreadCS);
mbGateway->mbThreadTCP = NULL;
}
Regards,
Ksawery
Re: Delete thread with blocking function
That's normal when you use Kill.since the thread destructor is never called:
Actually i'm not 100% sure about this. I wouldn't, but you can try what happens if you do.Should I delete the pointer manually after using Kill()?
Use the source, Luke!
Re: Delete thread with blocking function
you could not dream about correct killing thread if there is infinitely blocking function.
(that's why properly designed libraries MUST use timeouts).
variants
1. look if in your lib exists a timeouted function(often libs implement timeouted and not timeouted variants of the same function)
2. let your thread live till application end. he will die together with your application.
3. check if there could be a trick to send something to interface or device, to simulate incoming data, to resume blocked thread.
in reality in your sitaution case 2 is the most correct and simple.
bw the way, why tcp listening is not timeouted there???
(that's why properly designed libraries MUST use timeouts).
variants
1. look if in your lib exists a timeouted function(often libs implement timeouted and not timeouted variants of the same function)
2. let your thread live till application end. he will die together with your application.
3. check if there could be a trick to send something to interface or device, to simulate incoming data, to resume blocked thread.
in reality in your sitaution case 2 is the most correct and simple.
bw the way, why tcp listening is not timeouted there???
ubuntu 20.04, wxWidgets 3.2.1
Re: Delete thread with blocking function
pointer just points to the thread you have killed. nobody will set it to null except of you.Ksawery wrote: ↑Fri Oct 18, 2019 1:13 pm I use the following code to terminate the thread:
The application gets stuck in the while(1) loop, since the thread destructor is never called:Code: Select all
//Delete TCP/IP thread { wxCriticalSectionLocker enter(mbThreadCS); if (mbThreadTCP) { if (mbThreadTCP->Kill() != wxTHREAD_NO_ERROR) wxLogError("Can't delete the thread!"); } } while (1) { { wxCriticalSectionLocker enter(mbThreadCS); if (!mbThreadTCP) break; } wxThread::This()->Sleep(1); }
Should I delete the pointer manually after using Kill()?Code: Select all
cThreadTCP::~cThreadTCP() { close(socket); free(tcpQuery); wxCriticalSectionLocker enter(mbGateway->mbThreadCS); mbGateway->mbThreadTCP = NULL; }
Regards,
Ksawery
you sit in second loop because of it.
you killed thread object inside heap, os and scheduler, but your pointer still is not null.
your logic is wrong. just kill it and forget.
ps...
as doublemax i also not sure will Kill delete the thread object or not. seems not. because thread can be allocated statically.
if thread is "detached", then Kill MAYBE deallocates object.
Last edited by alys666 on Fri Oct 18, 2019 1:47 pm, edited 1 time in total.
ubuntu 20.04, wxWidgets 3.2.1
Re: Delete thread with blocking function
I still get the following message, despite using Kill():
So I guess I can't do anything until the blocking function returns? Im undertand though, that the thread is terminated, and the heap resources are freed anyway, when the app closes?
Code: Select all
15:41:27: Debug: 1 threads were not terminated by the application.
Last edited by Ksawery on Fri Oct 18, 2019 1:46 pm, edited 1 time in total.
Re: Delete thread with blocking function
Is it possible that libmodbus created an internal thread that's still running? Check the total number of threads of your application in the task manager.
When i google for libmodbus, i see a function modbus_set_response_timeout. Can you use that in your case?
https://libmodbus.org/docs/v3.0.6/modbu ... meout.html
When i google for libmodbus, i see a function modbus_set_response_timeout. Can you use that in your case?
https://libmodbus.org/docs/v3.0.6/modbu ... meout.html
Use the source, Luke!
Re: Delete thread with blocking function
debugger must show all app threads and and their names.
ubuntu 20.04, wxWidgets 3.2.1
Re: Delete thread with blocking function
app closing returns everything to OS. app works in virtual memory space, when you exit app, all threads will be killed, and all memory used by app will be marked as free.Ksawery wrote: ↑Fri Oct 18, 2019 1:41 pm I still get the following message, despite using Kill():
So I guess I can't do anything until the blocking function returns? Im undertand though, that the thread is terminated, and the heap resources are freed anyway, when the app closes?Code: Select all
15:41:27: Debug: 1 threads were not terminated by the application.
ubuntu 20.04, wxWidgets 3.2.1
Re: Delete thread with blocking function
Here are the threads running in the application:
There are more threads than I explicitly create, so I guess some must belong to libmodbus. I'm not sure how to terminate those.
Regards,
Ksawery
Code: Select all
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffddc8) at ../cPomiarWiazki.cpp:3
3 wxIMPLEMENT_APP(cPomiarWiazki);
[New Thread 0x7fffeb904700 (LWP 3993)]
[New Thread 0x7fffeb103700 (LWP 3994)]
[New Thread 0x7fffea3f1700 (LWP 3996)]
[New Thread 0x7fffe9bf0700 (LWP 3997)]
[New Thread 0x7fffe93ef700 (LWP 4001)]
[New Thread 0x7fffe8a70700 (LWP 4002)]
[Thread 0x7fffe8a70700 (LWP 4002) exited]
Regards,
Ksawery
Re: Delete thread with blocking function
cough...cough... it's definitely not linux
there is nothing in thread list, but addresses only ...
1. if your lib has internal threads and has not explicit functions kinda
stop_lib, terminate... you must not try to stop something inside it.
there is no big problem if you closed app with still working thread(s), OS will kill app process with his local threads.
in my apps I finish my threads, but app has other threads and who finishes them - it's not my business.
ps.
in reality you will have
1. mainthread(where you started main of you app)
2. some additional internal threads of system libs and wxWIdgets.
under linux i have : 3 system threads+main+created by me.
there is nothing in thread list, but addresses only ...
1. if your lib has internal threads and has not explicit functions kinda
stop_lib, terminate... you must not try to stop something inside it.
there is no big problem if you closed app with still working thread(s), OS will kill app process with his local threads.
in my apps I finish my threads, but app has other threads and who finishes them - it's not my business.
ps.
in reality you will have
1. mainthread(where you started main of you app)
2. some additional internal threads of system libs and wxWIdgets.
under linux i have : 3 system threads+main+created by me.
ubuntu 20.04, wxWidgets 3.2.1
Re: Delete thread with blocking function
Asking a 3rd time: Are you sure you can't set the timeout for the blocking function? That would solve everything.
Use the source, Luke!
Re: Delete thread with blocking function
What do you mean, this is under Linux Mint, Eclipse IDEcough...cough... it's definitely not linux
I don't think the library provides any way to interact with internal threads, although some people have suggested solutions:if your lib has internal threads and has not explicit functions kinda
stop_lib, terminate... you must not try to stop something inside it.
https://github.com/stephane/libmodbus/issues/173
Unfortunately, I don't think there is a way to set the timeout.Asking a 3rd time: Are you sure you can't set the timeout for the blocking function? That would solve everything.
I will try some of the suggested solutions on Monday. If these won't work, I will just allow the OS to terminate any threads when the App closes.
Many thanks,
Ksawery
Re: Delete thread with blocking function
I managed to find (what I hope is) a good solution to the problem, by following these recommendations:
https://github.com/stephane/libmodbus/issues/452
I made the TCP/IP socket non-blocking, using the following function:
This effectively makes the modbus_tcp_pi_accept() function non-blocking as well. The only downside to this, is that I need to poll the function repeatedly for new connections, which will use more CPU resources. However, as I understand from your previous recommendations, adding wxThread::This()->Sleep(1) in an "infinite" thread partially alleviates using too much CPU?
There is another TCP/IP function which is blocking: modbus_receive(). This function blocks the thread when a connection is established, but no messages are being received. Fortunately, a timeout for this function was provided, due to many user requests:
https://github.com/stephane/libmodbus/issues/95
So now i'm successfully able to terminate the thread, using the recommended code:
Many thanks,
Ksawery
https://github.com/stephane/libmodbus/issues/452
I made the TCP/IP socket non-blocking, using the following function:
Code: Select all
fcntl(socket, F_SETFL, fcntl(socket, F_GETFL, 0) | O_NONBLOCK);
There is another TCP/IP function which is blocking: modbus_receive(). This function blocks the thread when a connection is established, but no messages are being received. Fortunately, a timeout for this function was provided, due to many user requests:
https://github.com/stephane/libmodbus/issues/95
So now i'm successfully able to terminate the thread, using the recommended code:
Code: Select all
//Delete TCP/IP thread
{
wxCriticalSectionLocker enter(mbThreadCS);
if (mbThreadTCP)
{
if (mbThreadTCP->Delete() != wxTHREAD_NO_ERROR)
wxLogError("Can't delete the thread!");
}
}
while (1)
{
{
wxCriticalSectionLocker enter(mbThreadCS);
if (!mbThreadTCP) break;
}
wxThread::This()->Sleep(1);
}
Ksawery