Translate

2013-03-20

Forked processes and class destructors

Actually, it's universal advice for each language which provides facilities for OOP. Yesterday, I debugged issue appeared during unit-test run. Test just silently died without any verbose information about the reasons of such behavior. Lately, I discovered that test was killed by itself via TERM signal. But let me introduce a bit of pre-history.

Because of the lack of multi-threading support in DBI, as I described in previous post, I decided to move all internal processing machinery in our proprietary Perl module to multi-process model. Module is responsible for invoking a bunch of stored procedures on MySQL side in parallel fashion to utilize all computing power of hardware. There are no synchronization issues with locking in module because work is being spread among threads during creation stage and each thread does its part of work completely independently. Earlier, I had decided to use Perl threads but it was a flop (does somebody wish to bring multi-threading to DBI? I would be really grateful). I have Thread class in my module to represent a part of work which should be done in parallel. Firstly, you fill Thread instance with entities which represent different parts of work which should be performed in serial fashion. Then you invoke ->run method which returns instance of some kind of queue which is being used for synchronization and feedback in main thread/process. Everything is simple.

Troubles arose when I moved to using child processes internally in Thread class instead of Perl threads. The fact is that destructor was introduced in Thread class for finalizing communication pipe and killing child process. And from here, I would recommend to memorize following:

"Instances will be destroyed in each forked process during normal exit() routine."

If you deal with some system wide resources (named semaphores, processes) in your class internally (as I described above, I deal with child processes which I should sanitize appropriately during Thread destruction) you might to get into trouble.

"To avoid undesirable destructor invocation use _exit() routine"

I'm not sure if this routine is present everywhere but it is defined in POSIX. If we are talking about Perl, then you can get it from POSIX package. Something like POSIX::_exit. That's it.

No comments:

Post a Comment