Reputation: 15356
In my code the main loop looks like the following
while ( (data = foo()) != NULL ) {
// do processing on data here
}
where foo()
is written in C (it fetches the next frame in a video stream, using libavcodec, if you're curious).
My problem is that due to reasons too complicated to go in here, sometimes foo()
hangs, which stops the whole program. What I want to do is to detect this condition, i.e. foo()
is taking more than N seconds and if this is so take action.
I thought of creating a separate thread to run foo()
to implement this by I haven't done any multithreaded programming before. Here's what I want to do:
foo()
foo()
is done, the child thread returnsfoo()
foo()
doesn't return null
, which signals the end.How do I go about doing this? Do I need three threads (main, to run foo()
and for timing)?
Thanks!
Upvotes: 2
Views: 2475
Reputation: 7715
How do I go about doing this?
You don't. The hard thing is that there is no reliable way to stop a thread - assuming the hang is in libavcodec, interrupting/killing a thread stuck in code you do not have control over leads to more problems than it solves(it might just be memory and file handle leaks if you're not too unlucky). The thread has to stop itself - but that's not an option if you're stuck inside libavcodec.
Many threading implementation doesn't let you kill threads either - though you might request that the thread cancels , if it's stuck in a infinite loop, it'll never cancel though as the cancel requests are processed only at certain boundary points in the OS or low level library calls.
To work around a buggy library like that in a reliable way, you need process isolation. What you do is create a separate program out of your foo() function, execute that and communicated with it using its stdin/stout streams - or some other form of IPC. Talking to an external program, you have various options for doing I/O with timeouts, and can kill the program when you determin it's hanging.
Upvotes: 4
Reputation: 56038
On Linux you can use pthread_timedjoin_np
to make this happen with two threads really easily.
Upvotes: 1
Reputation: 14441
You'd probably be better off just fixing what ever is hanging your application.
Upvotes: 0
Reputation: 490048
This is exceedingly difficult to do well. The problem is what you're going to do when foo
hangs. Nearly the only thing you can do at that point is abort the program (not just the thread) and start over -- killing the thread and attempting to re-start it might work, but it's dangerous at best. The OS will clean up resources when you kill a process, but not when you kill a single thread. It's essentially impossible to figure out what resources belong exclusively to that thread, and what might be shared with some other thread in the process.
That being the case, perhaps you could move the hanging-prone part to a separate process instead, and kill/restart that process when/if it hangs? You'd then send the data to the parent process via some normal form of IPC (e.g., a pipe). In this case, you could have two threads in the parent (processor and watchdog), or (if available) you could do some sort of asynchronous read with time out, and kill the child when/if the read times out (using only one thread).
Upvotes: 7
Reputation: 5651
I think you can do this with two threads and use the sleep() command in the main thread for the timing part as long as you don't need to do other work there.
Upvotes: 0