Over a million developers have joined DZone.

Dawn Of The Thread

DZone's Guide to

Dawn Of The Thread

· DevOps Zone
Free Resource

The DevOps Zone is brought to you in partnership with Sonatype Nexus. The Nexus Suite helps scale your DevOps delivery with continuous component intelligence integrated into development tools, including Eclipse, IntelliJ, Jenkins, Bamboo, SonarQube and more. Schedule a demo today

In my previous post, Night of the Living Thread, I described how a dead Python thread may think it's still alive after a fork, and how I fixed this bug in the Python standard library. But what if you need to save your code from the ravenous undead in Python 2.6? The bug will never be fixed in Python 2.6's standard library. You're on your own. In Python 2.6, no one can hear you scream.

Recall from my last post that I can create a zombie thread like this:

t = threading.Thread()
if os.fork() == 0:
    # We're in the child process.
    print t.isAlive()

isAlive() should always be False, but sometimes it's True. The problem is, I might fork before the thread has added itself to the global _active list, so Python doesn't mark the thread as "stopped" after the fork. To fix this, I need t.start() to wait until the thread is completely initialized, so that I can't fork too soon.

Here's my solution, a SafeThread that will never rise from its grave:

class SafeThread(threading.Thread):
    def __init__(self, *args, **kwargs):
        super(SafeThread, self).__init__(*args, **kwargs)
        self.really_started = threading.Event()

    def start(self):
        super(SafeThread, self).start()

    def run(self):
        super(SafeThread, self).run()

I create an event in the SafeThread's constructor. Then in SafeThread.start(), I call the standard Thread's start method, but I wait for the event before returning. Finally, I trigger the event in run(), which is executed in the new thread. By the time the standard Thread executes run(), it has added itself to _active: thus, we know it's safe to set the event and unblock the thread that called start(). Even if I fork immediately after that, the Safethread is in _active and can't become zombified.

You can imagine more complex scenarios that will still defeat me. For example, Thread A could start Thread B, and Thread C could fork at the wrong moment and leave Thread B zombified. For absolute safety from zombies, upgrade to Python 2.7.6 or 3.3.3 when they're released with my bugfix. Meanwhile, SafeThread is good enough for the common case where the main thread creates the background thread and then forks.

(Get ready for the gory finale, Day of the Thread, in which humanity's last hope is to figure out the quirky code review system used by the Python Software Foundation.)

The DevOps Zone is brought to you in partnership with Sonatype Nexus. Use the Nexus Suite to automate your software supply chain and ensure you're using the highest quality open source components at every step of the development lifecycle. Get Nexus today


Published at DZone with permission of A. Jesse Jiryu Davis, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}