私は普段組み込みシステムのエンジニアです。
RTOSを使った組み込みシステムを開発しているとOSの機能を使って、イベント駆動アプリを制作するのが一般的です。
ですが、PythonではLinux等のように基本的に同期関数となっていて、一つのスレッドで複数のイベントを受け付けるのが標準のAPIでは実装しずらくなっています。
同期関数とは、呼び出したらその中が完了するまで処理が返ってこない関数のことです。
例としていうのであれば、Socket関数のrecv関数等がそういう作りになっています。
こういったことを解決するために、LinuxではSelect関数を使って、複数のIO入力を取得する方法があります。
そして、実はPythonにもSelectライブラリが組み込まれていて、同じような使い方ができるようになっているんです。
Select文サンプルコード
ですので、今回はPythonでのSelect文の使い方を紹介します。
では、まずいつも通りコードの全体をまず記載します。
import time
import threading
import socket
import select
Portnum = 12345
stop_application = False
def create_server(ip,port):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind( (ip,port) )
server.listen()
return server
def create_client(ip,port):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect( (ip,port) )
return client
def tm_callback( con ):
if stop_application == False:
snd = bytearray([5, 6, 7, 8])
con.send( snd )
def th1_func():
global stop_application
server = create_server('127.0.0.1',Portnum)
(con, client) = server.accept()
fd_set = set()
fd_set.add(con)
while True:
try:
if stop_application == False:
r, w, x = select.select(list(fd_set), [], [], 10)
for fd in r:
data = fd.recv(1024)
print(data)
time.sleep(0.1)
snd = bytearray([1, 2, 3, 4])
fd.send( snd )
else:
con.close()
break
except:
con.close()
break
def th2_func():
global stop_application
con = create_client('127.0.0.1',Portnum)
fd_set = set()
fd_set.add(con)
tm = threading.Timer( 1 , tm_callback,args=[con,] )
tm.start()
while True:
try:
if stop_application == False:
r, w, x = select.select(list(fd_set), [], [], 10)
for fd in r:
data = fd.recv(1024)
print(data)
time.sleep(0.1)
snd = bytearray([9, 10, 11, 12])
fd.send( snd )
else:
con.close()
break
except:
con.close()
break
def main_func( ):
global stop_application
thread1 = threading.Thread(target=th1_func)
thread1.start()
thread2 = threading.Thread(target=th2_func)
thread2.start()
while True:
try:
time.sleep(1)
except KeyboardInterrupt:
print("stop")
stop_application = True
thread1.join()
thread2.join()
break
if __name__ == '__main__':
result = main_func()
続いてはプログラムの解説ですが、解説は次ページにて記載します。
コメント