5

There are three python programs, writer program (writer.py) writes in to the file output.txt and two reader programs (reader_1.py, reader_2.py) read from the same output.txt file at a same time.

What is the best way to achieve the synchronization between these three programs? How to avoid reading by the reader program, if the other program is writing in to the output file? How to handle single writer and multiple readers problem efficiently in python?

I tried to implement the fnctl locking mechanism, but this module is not found in my python.

writer.py

#!/usr/bin/python
import subprocess
import time

cycle = 10

cmd="ls -lrt"

def poll():
   with open("/home/output.txt", 'a') as fobj:
      fobj.seek(0)
      fobj.truncate()
      try:
          subprocess.Popen(cmd,  shell=True,  stdout=fobj)
      except Exception:
          print "Exception Occured"

# Poll the  Data
def do_poll():
    count = int(time.time())

    while True:

        looptime = int(time.time())

        if (looptime - count) >= cycle:
             count = int(time.time())
             print('Begin polling cycle')
             poll()
             print('End polling cycle')

def main():
    do_poll()

if __name__ == "__main__":
    main()

reader_1.py

#!/usr/bin/python

with open("/home/output10.txt", 'r') as fobj:
   f=fobj.read()

print f

reader_2.py

#!/usr/bin/python

with open("/home/output10.txt", 'r') as fobj:
   f=fobj.read()

print f

Note: reader_1.py and reader_2.py runs continuously in while loop. Due to this reason same file being accessed by three programs at same time.

Looking for ideas.

Solution #1: Added fnctl locking mechanism to writer.py program. But not sure this is efficiently locking the file.

#!/usr/bin/python
import subprocess
import time
import os
import fcntl, os

report_cycle = 2

cmd='ls -lrt'

def poll(devnull):
   with open("/home/output10.txt", 'a') as fobj:
      try:
         fcntl.flock(fobj, fcntl.LOCK_EX | fcntl.LOCK_NB)
      except IOError:
          print "flock() failed to hold an exclusive lock."

      fobj.seek(0)
      fobj.truncate()

      try:
         subprocess.call(cmd, shell=True,  stdout=fobj, stderr=devnull)
      except Exception:
          print "Exception Occured"

      # Unlock file
      try:
           fcntl.flock(fobj, fcntl.LOCK_UN)
      except:
            print "flock() failed to unlock file."
user1720713
  • 184
  • 8
  • Which operating system are you using? – tdelaney Feb 20 '20 at 18:40
  • Linux (centos ) – user1720713 Feb 20 '20 at 19:32
  • `fcntl` is part of the base `cpython` on centos. Its a compiled C module. Are you using some other system? Perhaps you have a virtualenv that hasn't mapped it over? – tdelaney Feb 20 '20 at 19:42
  • Python version is 2.7, I am working on a physical system not in any virtual environment. cat /etc/redhat-release CentOS Linux release 7.7.1908 (Core) [root]# python Python 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import fnctl Traceback (most recent call last): File "", line 1, in ImportError: No module named fnctl – user1720713 Feb 20 '20 at 19:53
  • Spelling?! `fcntl`. – tdelaney Feb 20 '20 at 20:07
  • When i imported as "import fcntl, os" , no error is seen. – user1720713 Feb 20 '20 at 20:13
  • Nice. Just `import fcnt` fails, though? `os` is imported by python itself (`"os" in sys.modules.keys()`) so it shouldn't have any role here. But if it works... – tdelaney Feb 20 '20 at 20:25
  • Waiting for ideas – user1720713 Feb 21 '20 at 02:23
  • Was there an answer for this? Not able to see anything that clearly states what the solution is – Joe Ferndz Feb 09 '21 at 01:43
  • Have you tried any of the libraries mentioned here: https://stackoverflow.com/questions/489861/locking-a-file-in-python ? – Cheche Oct 25 '21 at 11:06

0 Answers0