I am currently on the topic of named pipes (a.k.a fifos, …, not to be confused with fee fi foe fum as is usually the case). Apparently, os.mkfifo() has been deprecated as of v3.12 (I am using v3.13). I have performed some searches but could not find any workarounds or substitutes.
The closest to a proposed substitute was discussed here:
I tried it but the os package library does not support it.
I noticed that when I performed a search, the AI response stated a potential workaround is using a text file as a liason much like this thread (user response):
that stated: I'm currently getting around the problem by just using text files. It works but it's not ideal – [iHnR]
Please note that I am using Window 11.
If not, has this function seen its last days (generally speaking of course since os.mkfifo has)? Or is a similar function found in a different library package? I am currently working on a sample problem in a tutorial so hoping to plug in a substitute if possible.
There’s lots of possibilities. It kind of depends on the program and data.
Is it multiple python apps or other types of apps talking to each other? What type of data is shared? Is it small amounts of data, or big amounts of data?
Most of the time I find that just using a socket on localhost and a given port of some sort winds up being a great way to pass things back and forth.
(Probably with either something like grpc or http on top of we want it to be production ready and cross language).
If just python and starting with one app, multiprocessing has options too.
Here is the sample test script. It is basically creating a parent and a child process for low level byte string access.
import os, time, sys
fifoname = r'C:\Desktop\pipefifo' # must open same name
def child():
pipeout = os.open(fifoname, os.O_WRONLY) # open fifo pipe file as fd
zzz = 0
while True:
time.sleep(zzz)
msg = ('Spam %03d\n' % zzz).encode() # binary as opened here
os.write(pipeout, msg)
zzz = (zzz+1) % 5
def parent():
pipein = open(fifoname, 'r') # open fifo as text file object
while True:
line = pipein.readline()[:-1] # blocks until data sent
print('Parent %d got "%s" at %s' % (os.getpid(), line, time.time()))
if __name__ == '__main__':
try:
if not os.path.exists(fifoname):
os.mkfifo(fifoname) # create a named pipe file
# Checks if there are arguments that are passed in or not:
if len(sys.argv) == 1:
parent() # run as parent if no args
else: # else run as child process
child()
except KeyboardInterrupt:
pass
From theory:
On some platforms, it is also possible to create a long-lived pipe that exists as a real named file in the filesystem. Such files are called named pipes (or, sometimes, fifos) because they behave just like the pipes created by the previous section’s programs.
So, for this example, was wondering if there is an equivalent to the fifo that I can use instead for this test script.
Here’s an example using sockets to do something similar to what you have (in a similar style). The code is missing error checking and logic to reconnect if the parent dies, but is a good starting point.
import os, time, sys, socket
port = 5558 # i picked this port randomly
def child():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect(('localhost', port))
zzz = 0
while True:
time.sleep(zzz)
msg = ('Spam %03d\n' % zzz).encode() # binary as opened here
sock.sendall(msg)
zzz = (zzz+1) % 5
def parent():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind(('localhost', port))
# listen to one connection
sock.listen(1)
conn, _ = sock.accept()
while True:
line = b''
while (b := conn.recv(1)) and b != b'\n':
line += b
print('Parent %d got "%s" at %s' % (os.getpid(), line, time.time()))
if __name__ == '__main__':
try:
# Checks if there are arguments that are passed in or not:
if len(sys.argv) == 1:
parent() # run as parent if no args
else: # else run as child process
child()
except KeyboardInterrupt:
pass
When running the parent and child (start the parent first):
C:\Users\csm10495\Desktop>python test.py
Parent 5808 got "b'Spam 000'" at 1739747816.4125166
Parent 5808 got "b'Spam 001'" at 1739747817.4133782
Parent 5808 got "b'Spam 002'" at 1739747819.4134982
Parent 5808 got "b'Spam 003'" at 1739747822.413607
Parent 5808 got "b'Spam 004'" at 1739747826.4143438
Parent 5808 got "b'Spam 000'" at 1739747826.4143438
Parent 5808 got "b'Spam 001'" at 1739747827.4147158
Parent 5808 got "b'Spam 002'" at 1739747829.415829
Parent 5808 got "b'Spam 003'" at 1739747832.416056
Parent 5808 got "b'Spam 004'" at 1739747836.4166045
Parent 5808 got "b'Spam 000'" at 1739747836.4166045
Parent 5808 got "b'Spam 001'" at 1739747837.417671
the child doesn’t currently print anything but could be changed to do whatever.
Yes, I am actually currently on the topic of learning working with sockets so this example fits right in. Though sockets are different from the os.mkfifo() function as they don’t have persistance.