gijzelaerr / python-snap7

A Python wrapper for the snap7 PLC communication library
http://python-snap7.readthedocs.org/
MIT License
643 stars 245 forks source link

[QUESTION] Concurrent read/write from multiple threads #307

Closed devaale closed 3 years ago

devaale commented 3 years ago

Hello, I'm sure it was answered before, but for some reason I'm unable to find info on this at the moment. Basically I have multiple threads working as "mini-services" in my program and they're communicating between each other using Queue in python. I have 4 services that are running in parallel (keep in mind all of them are reading / writing to their own separate blocks, neither of them will read or write to the same block):

  1. ReaderService - reads specific blocks data from PLC and sends that data to WriterService.
  2. WriterService - checks if read data changed, if yes - writes changed data to PLC and notifies ResultService.
  3. ResultService - process data and writes result to PLC
  4. ConnectionService - writes to a single plc block bool value, each time inverted (to notify PLC that connection is alive)

So my question is: What's the best and most importantly fastest (speed wise) implementation of trying to write/read data from multiple threads at the same time? Should I open up a separate connection for each service and allow PLC handle multiple calls at once or is it better to use locks on read/write functions on my side ? Can I even open up multiple connection to the same PLC ? Appreciate any help in advance.

lautarodapin commented 3 years ago

I'm not sure if this is going to help you But PLCs are one cored and can't handle multiple tasks at the same time I don't think you could improve more than you already did

xx1raven1xx commented 3 years ago

It would be interesting to see your code implementation...

swamper123 commented 3 years ago

Basically I have multiple threads working as "mini-services" in my program

Remember, Python has a GIL! They are scheduled by the OS in this case!

What's the best and most importantly fastest (speed wise) implementation of trying to write/read data from multiple threads at the same time?

Since the GIL is in your way, I would use async requests (I would use asyncio for such purposes). One Snap7 Client can just handle one request at the time. Even the async once! So it wouldn't make a difference of the amount of messages. What would improve with async stuff is, that you can do something else in the meantime, until an answer from the PLC arrives (and not wait in IDLE until something happens). You have to take a closer loop in the asyncio docs and check out the multithreadding/multiprocessing way. They have pools and queues there as well (maybe you find some inspiration there, but remember to check your used Python version).

Should I open up a separate connection for each service and allow PLC handle multiple calls at once or is it better to use locks on read/write functions on my side ?

I don't know if this would work tbh...if I remember right, some PLCs just allow up to 8 Clients max. for "Snap7-Connections". So that would be one limit of the connections. What I can't tell you is, if you would have one device with multiple clients doing stuff, if the right response returns to the right Client. Same IP, same Port ... but not sure if something is handled there under the hood to seperate the processes.

spreeker commented 3 years ago

Hi, blank_evaale,

Hi I would make a single service responsible for reading / writing stuff every single or x seconds to a PLC with read / write instructions coming from a queue.

The fastest Actions taken about 5 Ms. If you read the memory of an entire PLC it takes about few seconds.

An PLC is not a concurrent device so having multiple services reading and writing to it is not sensible.. imho. It is a different story if you write and read from many different PLC devices.

Hope this helps.

Stephan.

On Sun, Sep 5, 2021, 17:41 blank_evaale @.***> wrote:

Hello, I'm sure it was answered before, but for some reason I'm unable to find info on this at the moment. Basically I have multiple threads working as "mini-services" in my program and they're communicating between each other using Queue in python. I have 4 services that are running in parallel (keep in mind all of them are reading / writing to their own separate blocks, neither of them will read or write to the same block):

  1. ReaderService - reads specific blocks data from PLC and sends that data to WriterService.
  2. WriterService - checks if read data changed, if yes - writes changed data to PLC and notifies ResultService.
  3. ResultService - process data and writes result to PLC
  4. ConnectionService - writes to a single plc block bool value, each time inverted (to notify PLC that connection is alive)

So my question is: What's the best and most importantly fastest (speed wise) implementation of trying to write/read data from multiple threads at the same time? Should I open up a separate connection for each service and allow PLC handle multiple calls at once or is it better to use locks on read/write functions on my side ? Can I even open up multiple connection to the same PLC ? Appreciate any help in advance.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/gijzelaerr/python-snap7/issues/307, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAOSML6UD2LFTFMKY4UMTTUAOFQ5ANCNFSM5DO5WVNQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.