Thread priorities?

Tim Peters tim.peters at gmail.com
Tue Jun 14 21:57:49 CEST 2005


[Gary Robinson]
> In the application we're writing (http://www.goombah.com) it would be
> helpful for us to give one thread a higher priority than the others. We
> tried the recipe here:
> http://groups-beta.google.com/group/comp.lang.python/msg/6f0e118227a5f5de
> and it didn't seem to work for us.

If you need to fiddle thread priorities, then you'll need to do such
platform-specific things, and fight with the OS documentation to
figure out when and why they don't seem to work.

> We don't need many priority levels. We just need one thread to
> *temporarily* have a higher priority than others.
>
> One thing that occurred to me: There wouldn't by any chance be some way
> a thread could grab the GIL and not let it go until it is ready to do
> so explicitly?

No, unless that thread is running in a C extension and never calls
back into Python until it's willing to yield.

> That would have the potential to solve our problem.
>
> Or maybe there's another way to temporarily let one thread have
> priority over all the others?

No way in Python, although specific platforms may claim to support
relevant gimmicks in their native threads (and Python threads
generally are native platform threads).

A portable approach needs to rely on thread features Python supports
on all platforms.  For example, maybe this crude approach is good
enough:

"""
import threading

class Influencer(object):
    def __init__(self):
        self.mut = threading.Lock()
        self.proceed = threading.Event()
        self.proceed.set()
        self.active = None

    def grab(self):
        self.mut.acquire()
        self.active = threading.currentThread()
        self.proceed.clear()
        self.mut.release()

    def release(self):
        self.mut.acquire()
        self.active = None
        self.proceed.set()
        self.mut.release()

    def maybe_wait(self):
        if (self.proceed.isSet() or
              self.active is threading.currentThread()):
            pass
        else:
            self.proceed.wait()
"""

The idea is that all threads see an (shared) instance of Influencer,
and call its .maybe_wait() method from time to time.  Normally that
doesn't do anything.  If a thread T gets it into its head that it's
more important than other threads, it calls .grab(), which returns at
once.  Other threads then block at their next call to .maybe_wait(),
until (if ever) some thread calls .release().  Season to taste; e.g.,
maybe other threads are willing to pause no more than 0.1 second; etc.



More information about the Python-list mailing list