-1

I have a C++98 project that uses Boost-Thread. The main thread creates 12 threads like this:

for(int i=0;i<numCPU;++i)
{
    vThreads.push_back(new boost::thread(boost::bind(&TControl::startCPU,this,i,fnp)));
}

and the worker threads run as long as getWork() returns workunits:

void startCPU(int id,StartFn fnp)
{
    unused(id);
    while(true)
    {
        WU_TYPE* pWU(getWork());
        if(pWU==NULL) return;
        CALL_MEMBER_FN(pWU,fnp)();  
    }
}

Certain workunits may run very long. The goal is now to kill workunits that have already more than 60 minutes runtime so that the thread (that runs void startCPU() ) can start a new workunit.

Initially I thought that this can be done by signals, i.e., the main thread could raise a signal every minute and a signal handler inside each thread could throw an exception for overdue workunits. But after a bit reading it doesn't seem to work like this because signals raised from one thread do not launch the signal handler of another thread, right? What is an appropriate technique to achieve this goal?

Note: C++11 is not available, the software must compile on old systems.

Geom
  • 827
  • 4
  • 15
  • remember start time before while -> check current time in while -> if exit time is reached leave while -> set variable which shows the working unit that this thread finished. – Detonar Dec 22 '17 at 09:57
  • CALL_MEMBER_FN runs the member function pointer fnp of the workunit pWU and does not return until the workunit is done. The goal is to interrupt fnp() every minute and check if it shall be killed. – Geom Dec 22 '17 at 10:03

1 Answers1

0

Without support from the code that is currently running in the thread, it cannot be done. Threads share a process context. They acquire locks and then corrupt the context and they must return the context to a sane state prior to releasing the lock or the process context will be damaged. So you cannot kill a thread without the cooperation of the code it's currently running.

With its cooperation, you can use whatever method it supports. If the code supports Boost's interrupt function, you can use that. The code must implement "interruption points", checking if it has been interrupted and cleanly terminating the thread -- otherwise, interrupt won't do anything. If it supports some other mechanism, use that. But it must be designed in from the beginning.

Otherwise, isolate the code with a process rather than a thread. You can terminate a process as long as you aren't doing anything weird (like sharing memory with it).

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Thanks. But the thread shall not be killed: I launch only 12 threads that run void startCPU(). In startCPU() many workunits are executed iteratively and I just want to kill large workunits. I have already a progress bar object that is frequently updated from the algorithm and I can throw an exception there. But this is not a good solution because the algorithm might take unexpectedly much time in a loop where the progress bar is not updated. Therefore I thought interrupting via signals would be a better solution – Geom Dec 22 '17 at 10:17
  • @Geom It's almost certainly not. But if you want to make all your code signal safe, it can work. – David Schwartz Dec 23 '17 at 21:55