FC2ブログ

Python/Lua:PIPE 1本で双方向+EVENT

2019-05-15 :  PCクリニック
Lua系とPythonとの関連において、
“クライアント/サーバ”システムに関する記事を若干書いている:
これまでの記事は10件強

中で、
2017年02月03日の記事:
クライアント/サーバ:PIPE 1本で双方向+EVENT
は、“GSL Shell”→“GSL Shell”のパターン

  前の記事「クライアント/サーバ:PIPE 1本で双方向通信」に続いて、
  イベントは無くても良さそう(?)だったが、
  正統?“ハンドシェイク通信”とすべく、EVENT 同期を追加した。
  ・・・・・
  ・・・・・

この時の処理概要は:

  1.クライアント側からサーバ側を起動する様にする
     クライアント:Master_Client.gsl
     サーバ:Slave_Server.gsl
  2.PIPE は、これまで通りサーバ側で作成し、
    EVENT は、クライアント側で準備する。
     イベント(signal)の初期値は、off とする。
  3.signal 状態:
     クライアント側から送ったら、off
     サーバ側から送り返したら、on
  4.サンプルコード:
     クライアント側でキーボード入力し、
     サーバに送信し、
     サーバ側では、文字列を加工し、
     クライアント側に送り返す。
     キー入力が 'e' で処理終了。


そして、
続く、2017年02月05日の記事:
Lua/Python:PIPE 1本で双方向+EVENT
は、“GSL Shell”→“Python”のパターン(未完成)

  前(2017-02-03)の記事「クライアント/サーバ:PIPE 1本で双方向+EVENT」で、
    ・・・・・
    ・・・・・
    “Master_Client.gsl”をダブルクリックすると、・・・
    出来ました。
    ・・・・・
    ・・・・・
  と、
  GSL Shell 同士では、一応の完成を見た?ので、・・・

  今度は、
  サーバ側 Slave_Server.gsl を、Python に移植したい。
  ・・・・・
  ・・・・・

  Python には、
  “イベントオブジェクト取得”に相当する関数が無い?

  win32event にあるのは、

  win32event.CreateEvent( None, 1, 0, 'EVENT1' )
  # イベントハンドルを非シグナルで作成。

  この“CreateEvent”関数だけ?
  この関数で、
  “イベントオブジェクト作成”&“イベントオブジェクト取得”
  となる様ダ。

  と云うことは、
  “イベントオブジェクト作成”は、Python 側で!
  そうすると、
  “パイプの作成”は、GSL Shell 側で?

  出直して来ます。


と云うことで、

続く、2017年02月06日の記事:
Lua から Python:PIPE 1本で双方向+EVENT
で、“GSL Shell”→“Python”のパターン(完成)

この時の処理概要は:

  1.クライアント側からサーバ側を起動する様にする
     クライアント:Master_Client.gsl
     サーバ:Slave_Server.py
  2.PIPE は、クライアント側で作成してから、サーバを起動する
    EVENT は、サーバ(Python)側で準備する。
     イベント(signal)の初期値は、off とする。
  3.signal 状態:
     クライアント側から送ったら、off
     サーバ側から送り返したら、on
  4.サンプルコード:
     クライアント側でキーボード入力し、
     サーバに送信し、
     サーバ側では、文字列を加工し、
     クライアント側に送り返す。
     キー入力が 'e' で処理終了。



さて、ここからが本題。


今度は、
主客(?)ところを変えて、
“Python”→“GSL Shell”(LuaJIT) のパターンを作る。


処理概要としては:

  1.クライアント側からサーバ側を起動する様にする
     クライアント:Main_Client.py
     サーバ:Sub_Server.lua
  2.EVENT は、クライアント(Python)側で準備(作成)し、
     イベント(signal)の初期値は、off とする。
        ここで、サーバを立ち上げる。
     PIPE は、サーバ(GSL Shell)側で作成する。
  3.signal 状態:
     クライアント側から送る時、off にする。
     サーバ側からは、on にして送る。
  4.サンプルコード:
     クライアント側でキーボード入力し、
     サーバに送信し、
     サーバ側では、文字列を加工し、
     クライアント側に送り返す。
     キー入力が 'e' で処理終了。



ここでも、
クライアント/サーバ:PIPE 1本で双方向+EVENT」で作った、
サブプログラム「cdef_PIPE_Event_SUB.lua」に対して、
PIPE 1本双方向+EVENT:Lua から Python でグラフ出力」で
書いた様に、若干追加したものを利用した。


それから、
1件学習した:
Pythonでプログラム起動して待たない」方法
つまり、
Run Process and Don't Wait
これの回答 [45]:
  This call doesn't wait for the child process to terminate (on Linux).
  Don't ask me what close_fds does; I wrote the code some years ago.
  (BTW: The documentation of subprocess.Popen is confusing, IMHO.)
===
  この呼び出しは、子プロセスが終了するのを待ちません(Linuxの場合)。
  close_fdsが何をするのか私に聞かないでください。
   私は数年前にコードを書いた。
  (ところで:subprocess.Popenのドキュメントは混乱しています、私見)
proc = Popen([cmd_str], shell=True,
stdin=None, stdout=None, stderr=None, close_fds=True)
( 今までのものは、処理が終了するまで待っていた )

   ( BTW = ところで ? )、( IMHO = 私意 ? ) By「Google 翻訳」

   ( BTW = By The Way ? )、( IMHO = In My Honest Opinion ? )
   By「https://www.abbreviations.com/」



出来たのは、
# coding: utf-8
# ----- Main_Client.py
import win32event, win32pipe, win32file, subprocess, time

# ----- 初期化1:イベントハンドルを非シグナルで作成。
E1 = win32event.CreateEvent( None, 1, 0, 'EVENT1' )
# ----- 初期化2:サーバー立ち上げ
subprocess.Popen( 'luajit Sub_Server.lua', shell=True, stdin=None, stdout=None, stderr=None, close_fds=True )

# ----- 立ち上げ確認:シグナル状態チェック for PIPE Open
while True: # on 迄
if win32event.WaitForSingleObject( E1, 0 ) == 0: break

#-- PIPE オープン
P1 = win32file.CreateFile("\\\\.\\pipe\\PIPE1",
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
0, None, win32file.OPEN_EXISTING, 0, None);

# シグナル off にする。
win32event.ResetEvent( E1 )
# ---------------------- 処理:無限ループ
while True:
print( 'Input: e for END' )
str = raw_input() # キー入力

# シグナル off にして、リクエスト送信
win32event.ResetEvent( E1 )
win32file.WriteFile( P1, str )
if str == 'e': break

# シグナル状態チェック -- on 迄
while True:
if win32event.WaitForSingleObject( E1, 0 ) == 0: break
# ---- 結果受信
_, str = win32file.ReadFile( P1, 4096 )

print( str )
と、
----- Sub_Server.lua
require'cdef_PIPE_Event_SUBx'

----- マスタ(クライアント)から呼ばれた:
-- イベントオブジェクト取得
E1 = C.OpenEventA( 0x001F0003, 0, charA('EVENT1') ) -- EVENT_ALL_ACCESS

-- パイプを作成
P1 = C.CreateNamedPipeA( charA("\\\\.\\pipe\\PIPE1"), 3, 0, 1, 0, 0, 100, 0 )

-- シグナル状態にする。
C.SetEvent( E1 )

-- Client オープン待ち
rtn=C.ConnectNamedPipe( P1, 0 )

------------------------ 処理:無限ループ
while true do
-- シグナル状態チェック -- off 迄
repeat until band( C.WaitForSingleObject( E1, 1 ), 2 ) ~= 0
-- リクエスト受信
rtn=C.ReadFile( P1, charA(Buf), 4097, nIO, 0 )
if rtn==0 then break end

str=ffi.string(Buf,nIO[0])
if str=='e' then break end

C.Sleep(200) ------ ダミー処理

-- シグナル on にして、結果送信
C.SetEvent( E1 )
rtn=C.WriteFile( P1, charA(str..'HOGE'), nIO[0]+4, nIO, 0 )
end

C.FlushFileBuffers( P1 )
C.DisconnectNamedPipe( P1 )
C.CloseHandle( P1 )

こんなところかナ?



本日はここまで。


LuaJIT / Anaconda ( Python ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒

190403
関連記事
スポンサーサイト



コメントの投稿

管理者にだけ表示を許可する

人気blog Ranking



最新記事
カレンダー
07 | 2021/08 | 09
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

FC2 / i2i / Google




Google Analytics
ブックマーク