简体   繁体   中英

Python message passing to unique threads

I have an application (actually a plugin for another application) that manages threads to communicate with external sensor devices. The external sensors send events to the application, but the application may also send actions to the sensors. There are several types of devices and each has unique qualities (temperature, Pressure, etc.) that require special coding. All communications with the sensor devices is over IP.

In the applications, I create a thread for each instance of a sensor. This is an example of the code

self.phThreadDict[phDevId] = tempsensor(self, phDevId, phIpAddr, phIpPort, phSerial, self.triggerDict)
self.phThreadDict[phDevId].start()

In each thread I setup callback handlers for events sent by the sensor and then go into a loop at the end.

while not self.shutdown:
    self.plugin.sleep(0.5)

The threads then handle incoming events and make calls into the main thread, or the actual program that spawned the main thread. All of this works quite well.

But, at times I also need to send requests to a specific sensor. Methods are defined in each thread for that purpose and I call those methods from the main thread. For example:

self.phThreadDict[dev.id].writeDigitalOutput(textLine, lcdMessage)

This also works, but I believe the code is actually executed in the main thread rather than in the thread specific to the sensor.

My question is: What options do I have for passing work to the specific target thread and having the thread execute the work and then return success or fail?

Expanding a bit on Thomas Orozco's spot-on comments,

self.phThreadDict[dev.id].writeDigitalOutput(textLine, lcdMessage)

is executed in whichever thread runs it. If you run it from the main thread, then the main thread will do all of it. If from some other thread, then that thread will run it.

In addition to a Queue per thread, for the threads to receive descriptions of work items to process, you also want a single Queue for threads to put results on (you can also use another Queue per thread for this, but that's overkill).

The main thread will pull results off the latter Queue . Note that you can - and it's very common to do so - put tuples on Queues . So, for example, on the talk-back-to-the-main-thread Queue threads will likely put tuples of the form:

(result, my_thread_id, original_work_description)

That's enough to figure out which thread returned what result in response to which work item. Maybe you don't need all of that. Maybe you need more than that. Can't guess ;-)

Indeed, this is executing code in the main thread.


Use queues , that's what they're meant for (task synchronization and message passing between threads).

Use one queue per sensor manager thread.

  • Your sensor manager threads should be getting items from the queue instead of sleeping (this is a blocking call).
  • Your "main" thread should be putting items in the queue instead of running functions (this is generally a non-blocking call).

All you need to do is define a message format that lets the main thread tell the manager threads what functions to execute and what arguments to use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM