SORU
27 Kasım 2008, PERŞEMBE


Python bir iş Parçacığı öldürmek için herhangi bir yolu var mı?

///Etc semafor bayrakları ayarı herhangi bir kontrol olmadan çalışan bir iş parçacığı sona erdirmek mümkün mü.?

CEVAP
28 Kasım 2008, Cuma


Genellikle bir konu aniden, herhangi bir dil Python ve öldürmek için kötü bir kalıptır. Aşağıdaki durumlarda düşünün:

  • iplik düzgün bir şekilde kapatılması gereken kritik bir kaynak tutuyor
  • iplik de öldürülmesi gereken birkaç diğer konuları oluşturdu.

Güzel bir şekilde işleme bu paran yeterse bunu (eğer sen yönetmek senin kendi iş parçacığı) bir exit_request bayrağı her iş parçacığı kontrolleri düzenli aralıklarla, eğer o zaman onunla çık.

Örneğin:

import threading

class StoppableThread(threading.Thread):
    """Thread class with a stop() method. The thread itself has to check
    regularly for the stopped() condition."""

    def __init__(self):
        super(StoppableThread, self).__init__()
        self._stop = threading.Event()

    def stop(self):
        self._stop.set()

    def stopped(self):
        return self._stop.isSet()

Bu kod, dur demelisin() çıkın ve iplik düzgün katılın kullanarak çıkmak için beklemek istiyorsanız bu konu üzerinde(). Konu düzenli aralıklarla dur bayrağı kontrol etmelisiniz.

Gerçekten bir iş parçacığı öldürmek için gereken zaman ancak durumlar vardır. Bir örnek, uzun aramalar için yoğun bir dış kütüphane sarma zaman bunu bölmek istiyorum.

Aşağıdaki kodu sağlar (bazı kısıtlamalarla) Python bir iş parçacığı bir özel Durum oluşturmak için

def _async_raise(tid, exctype):
    '''Raises an exception in the threads with id tid'''
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
                                                  ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        # "if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
        raise SystemError("PyThreadState_SetAsyncExc failed")

class ThreadWithExc(threading.Thread):
    '''A thread class that supports raising exception in the thread from
       another thread.
    '''
    def _get_my_tid(self):
        """determines this (self's) thread id

        CAREFUL : this function is executed in the context of the caller
        thread, to get the identity of the thread represented by this
        instance.
        """
        if not self.isAlive():
            raise threading.ThreadError("the thread is not active")

        # do we have it cached?
        if hasattr(self, "_thread_id"):
            return self._thread_id

        # no, look for it in the _active dict
        for tid, tobj in threading._active.items():
            if tobj is self:
                self._thread_id = tid
                return tid

        # TODO: in python 2.6, there's a simpler way to do : self.ident

        raise AssertionError("could not determine the thread's id")

    def raiseExc(self, exctype):
        """Raises the given exception type in the context of this thread.

        If the thread is busy in a system call (time.sleep(),
        socket.accept(), ...), the exception is simply ignored.

        If you are sure that your exception should terminate the thread,
        one way to ensure that it works is:

            t = ThreadWithExc( ... )
            ...
            t.raiseExc( SomeException )
            while t.isAlive():
                time.sleep( 0.1 )
                t.raiseExc( SomeException )

        If the exception is to be caught by the thread, you need a way to
        check that your thread has caught it.

        CAREFUL : this function is executed in the context of the
        caller thread, to raise an excpetion in the context of the
        thread represented by this instance.
        """
        _async_raise( self._get_my_tid(), exctype )

Belgelerinde belirtildiği gibi, bu konu Python yorumlayıcısı dışında meşgul ise, kesinti yakalamak değil çünkü sihirli bir değnek değildir.

Bu kod iyi kullanım desen iplik belirli bir özel durumu yakalamak ve temizleme işlemini gerçekleştirmek için. Bu şekilde, bir görev kesme ve hala uygun bir temizleme olabilir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • MrOctopi

    MrOctopi

    6 Aralık 2010
  • MW Technology

    MW Technolog

    28 EKİM 2009
  • tatermoog

    tatermoog

    2 AĞUSTOS 2006