0

I have a specific problem.

  1. Main content of program starts with creating Process with dbus loop, where I listen for signals.
  2. Content of signals I store in queues. In next part of main I have a threadpool.
  3. When some thread takes item from queue, it use specific function(detection) to handle request - based on content of item from queue. (There is operation on database, from where I take data and make some operations depends on request)
  4. Every thread in thread pool starts one more thread, which should handle signals (current status and interrupt).

For example: I receive signal, which means I have to handle something on numbers. Any thread from threadpool takes this item from queue and starts function which handle something on numbers - it can take long time. So after any time, I receive signal for current status and I need to send current status of detection - that's why I use threads (for shared memory). Also I can receive interrupt signal from D-Bus ("it takes too long time, so stop this detection and be free for another request"). And the interrupt is the main problem...

So my main questions are:

  1. Is there any way, I can raise exception on interrupt signal and stop function (detection)? (I just found solution, but only for catch in main... but I need to catch it in thread which is in threadpool and raise in thread which is in thread in threadpool)
  2. Second question is about GIL... does my thread with signal receiving receive all signals? I think it doesn't... (Yes, I use threads_init())

program:

SERVICE = multiprocessing.Process(target=dbus_signal_receiver, args=(...))
SERVICE.daemon = True
SERVICE.start()

class worker(threading.Thread):
    def __init__(self,...):
        threading.Thread.__init__(self)

    def run(self):
        while True:
            #get item from queue
            s = threading.Thread(target=curr_and_interr_signal_handle, args=(ID of item from queue,...))
            s.daemon = True
            s.start()
            #start specific detection based on request

for i in range(number of threads):
    t = worker(...)
    t.daemon = True
    t.start()

and I hoped, something like this will work... (but it doesn't)

...

class worker(threading.Thread):
    def __init__(self,...):
        threading.Thread.__init__(self)

    def run(self):
        while True:
            try:
                #get item from queue
                s = threading.Thread(target=curr_and_interr_signal_handle, args=(ID of item from queue,...))
                s.daemon = True
                s.start()
                #start specific detection based on request
            except raised_interrupt_exception:
                #continue - wait for another request from queue


...
M. Ohio
  • 1
  • 2

1 Answers1

0

Read about 18.8.1.2. Signals and threads
Python signal handlers are always executed in the main Python thread, even if the signal was received in another thread.
This means that signals can’t be used as a means of inter-thread communication.
You can use the synchronization primitives from the threading module instead.
Besides, only the main thread is allowed to set a new signal handler.

Read about 17.1.7. Event Objects
This is one of the simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it


Isn't clear why you have to use thread in thread.
Why could your worker thread not handle detection?

For instance, the following should be do it:

def run(self):
    while self.running.is_set():
        #get item from queue
        #start specific detection based on request
stovfl
  • 14,998
  • 7
  • 24
  • 51
  • Thread in thread I use because of every item (request) in queue, which I get in threadpool, has it's own unique ID. So every thread in threadpool starts thread for handle signals from D-Bus about current status of detection and interrupt to stop handling request with ID. When interrupt, stop function in thread which handle this ID and continue for getting another item (request) from queue – M. Ohio May 04 '17 at 08:47
  • For example: I get D-Bus signal which means interrupt request with ID 55. And because this thread - `s = threading.Thread(target=curr_and_interr_signal_handle, args=(...))` - on start gets ID of item from queue, it can raise any exception if the ID of actual handle item from queue is the same as signal interrupt request ID. But this raised exception I am not able to catch properly. – M. Ohio May 04 '17 at 09:05
  • Have you got better way to deal with it? – M. Ohio May 04 '17 at 09:12
  • @M.Ohio: Reading your comments does not open up my understanding why you have raise any exception. But anyway, I have updated my Answer. – stovfl May 04 '17 at 09:54
  • Do you know D-Bus? Its control bus for communication between applications. My aplication gets signals (messages) from D-Bus, must receive them and based od type handle it. If it is request for currect status of item with ID = X, my app send actual status in percentage of it's ID. If it is message, which means interrupt item with ID = X, so in thread which handle interrupt messages and ID of item is same as received, I have to stop executing detection and wait for another item from queue. Detection means object, which operate something on huge dataset. – M. Ohio May 04 '17 at 10:44
  • I can just do something like -> if interrupt message received, set variable from object, for example self.interrupt=True, and in any loop etc just check it. But it is not very comfortable if I have a lot of types of detections and not everyone has any loop... Thats why I wanted raise any exception and catch it as I show in my question. – M. Ohio May 04 '17 at 10:47
  • @M.Ohio: Maybe this is what you want http://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python – stovfl May 04 '17 at 19:20
  • Kill thread isn't, what I need... because I just want continue for another task. After X interrupts (where X is number of threads in threadpool), my program won't be able to get another tasks...? But thanks, it looks I just can think about some rework... – M. Ohio May 05 '17 at 06:52