I have a number of worker threads which all perform a flood-fill task on different regions of a bitmap. They all make calls to a recursive sub-routine with different parameters(coordinates). Fyi, I am using a scan-line method.
I have implemented a reset feature which aims to kill these processes so that they would start again.
The way I have currently implemented my killing mechanism, is to use a kill Event with manual reset and make the flood-fill subroutine return if it is signaled. This way, the threads will still visit a considerable number of points on the region they are bounded to, before blissfully giving up, but nevertheless skip the relevant filling operation. I was wondering if there is a more efficient way of doing this.
P.S. Yes I know it’s an over-kill for flood-fill, but this is a general question. One could imagine a matrix where you would want to perform some expensive local operations based on some local conditions and use a recursive routine of the same nature as an scanline approach.
EDIT:
Here is the current design of my framework:
m_pThread[i] = AfxBeginThread(FloodFill_Sub_ThreadProc, (LPVOID)m_pFloodFillInput[i], 0, 0, CREATE_SUSPENDED);
with threadprocedures defined as:
UINT CTestShellDlg::FloodFill_Sub_ThreadProc(LPVOID pData)
{
...
FloodFill_Sub(mid, mid, Color_old, Color_new);
}
and finally the FloodFill_Sub:
void CTestShellDlg::FloodFill_Sub(CPoint& node, CPoint& mid, COLORREF Color_old, COLORREF Color_new) /*Sub-routine to be used by threads*/
{
if (KillEventTriggered())
return;
if (RecursionTerminationCondition)
return;
//loop some scans and make recursive calls to FloodFill_Sub
...
}
Now in the looping section, one could add further KillEventTriggered() checks, But I am wondering if there could be a better approach.
There is no clean and safe way to quickly/efficiently “kill” a thread. You can signal to the thread object that it needs to terminate, but the thread needs to be written in such a way that it checks for this and then cleans itself up. Otherwise, you can end up with partially-completed operations, memory leaks, resource leaks, deadlocks, and all manner of chaos in your program.
Whether or not the threads involved are performing a recursive operation and spawning sub-threads really doesn’t change this basic principle.
3