サーバーとコンソール プログラムを同じプロセスにする理由はありますか?
そうでない場合は、2 つの別個のプロセスと名前付きパイプを使用することをお勧めします。この解決策が何らかの理由で理想的でない場合は、詳細を教えてください。
とにかく、Pipe クラスを実装するのに役立つコードをいくつか示します。通信する必要があるデータがどのような形式であるかは正確にはわかりません。そのため、Pipe クラスで単純なプロトコルを抽象化したり、pickle を使用したりできます。
def __init__(self,sPath):
"""
create the fifo. if it already exists just associate with it
"""
self.sPath = sPath
if not os.path.exists(sPath):
try:
os.mkfifo(sPath)
except:
raise Exception('cannot mkfifo at path \n {0}'.format(sPath))
self.iFH = os.open(sPath,os.O_RDWR | os.O_NONBLOCK)
self.iFHBlocking = os.open(sPath,os.O_RDWR)
def base_read(self,iLen,blocking=False):
iFile = self.iFHBlocking if blocking else self.iFH
while not self.ready_for_reading():
import time
time.sleep(0.5)
lBytes = ''.encode('utf-8')
while len(lBytes)<iLen:
self.lock()
try:
lBytes += os.read(iFile,1)
self.unlock()
except OSError as e:
self.unlock()
if e.errno == 11:
import time
time.sleep(0.5)
else:
raise e
return lBytes
def base_write(self,lBytes,blocking = False):
iFile = self.iFHBlocking if blocking else self.iFH
while not self.ready_for_writing():
import time
time.sleep(0.5)
while True:
self.lock()
try:
iBytesWritten = os.write(iFile, lBytes)
self.unlock()
break
except OSError as e:
self.unlock()
if e.errno in [35,11]:
import time
time.sleep(0.5)
else:
raise
if iBytesWritten < len(lBytes):
self.base_write(lBytes[iBytesWritten:],blocking)
def get_lock_dir(self):
return '{0}_lockdir__'.format(self.sPath)
def lock(self):
while True:
try:
os.mkdir(self.get_lock_dir())
return
except OSError as e:
if e.errno != 17:
raise e
def unlock(self):
try:
os.rmdir(self.get_lock_dir())
except OSError as e:
if e.errno != 2:
raise e
def ready_for_reading(self):
lR,lW,lX = select.select([self.iFH,],[],[],self.iTimeout)
if not lR:
return False
lR,lW,lX = select.select([self.iFHBlocking],[],[],self.iTimeout)
if not lR:
return False
return True
def ready_for_writing(self):
lR,lW,lX = select.select([],[self.iFH,],[],self.iTimeout)
if not lW:
return False
return True
共有したいクラスのより完全な実装がありますが、抽象化したプロトコルはおそらく役に立たないと思います...これを使用する方法は、サーバーとコンソールアプリケーションでインスタンスを作成することです同じパス。次に、base_read と base_write を使用して、汚い作業を行います。ここにある他のすべてのものは、奇妙な競合状態を避けるためのものです。
お役に立てれば。