並行処理できて、なおかつ情報をまとめて受信したい時にパッと思いついたのがsocket通信でしたが、試行錯誤した結果、multiprocessing
のPipe
で実装を行いました。今回はsocketとPipeの比較をメモ程度に。
結論から言うと、送信内容をすぐに受信するのであれば両方とも変わりありませんが、受信内容をまとめて受け取る処理の場合はpipeの方が扱いやすかったです。
#socket通信のテストコード
ローカル通信を利用して、パソコン内のpyファイル同士で文字列の送受信を行います。
具体的にはサーバ側から文字列を送信し、クライアント側はまとめて受信するために受信処理を遅延させます。
# -*- coding:utf-8 -*-
#!/usr/bin/python
import numpy as np
import socket
import sys
#環境に応じて変更
HOST = '127.0.0.1'
PORT = 50900
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.bind((HOST, PORT))
socket1.listen(1)
# コネクションとアドレスを取得
connection, address = socket1.accept()
# 文字列を3回送る
for i in range(3):
txt = "abcd".encode('utf-8')#
connection.send(txt)
# サーバの処理終了防止
x = input()
# -*- coding:utf-8 -*-
#!/usr/bin/python
import socket
import time
import sys
#IPアドレスとポート番号は環境に応じて変更
HOST = "127.0.0.1"
PORT = 50900
sock1=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#タイムアウト防止
while True:
try:
sock1.connect((HOST,PORT))
except ConnectionRefusedError:
continue
break
# 受信処理を遅延
time.sleep(5)
# server.pyからの受信と表示
txt = sock1.recv(1024).decode()
print(txt)
###結果
クライアント→サーバの順に起動。
abcdabcdabcd
文字列が連なってしまって、扱うのが少々面倒くさいです。
#Pipeのテストコード
処理条件はほぼ変わらず。
# -*- coding:utf-8 -*-
#!/usr/bin/python
from multiprocessing import Pipe
import time
a, b = Pipe()
# 文字列を3回送る
for i in range(3):
a.send("abcd")
# 受信処理を遅延
time.sleep(5)
# pipeの受信と表示
print(b.recv())
###結果
abcd
送信した文字列をそのまま受け取ることができましたが、実際はabcd
の文字列が後ろに待機している状態となっています。そこで、受信内容を全て受け取れるよう、以下のように変更します。
# -*- coding:utf-8 -*-
#!/usr/bin/python
from multiprocessing import Pipe
import time
a, b = Pipe()
mai_list = []
# 文字列を3回送る
for i in range(3):
a.send("abcd")
# 受信処理を遅延
time.sleep(5)
# pipeの受信と表示(ない場合はpass)
if b.poll() is True:
while b.poll() is True:
mai_list.append(b.recv())
print(mai_list)
すると、受信内容が以下のようにlist型となって返ってきます。
['abcd', 'abcd', 'abcd']
これで受信内容が扱いやすくなりました。
因みにPipe
における並行処理については、multiprocessing
モジュールのProcess
を利用することで実装ができます。
# -*- coding:utf-8 -*-
#!/usr/bin/python
from multiprocessing import Pipe
from multiprocessing import Process
import time
a, b = Pipe()
mai_list = []
def send(a):
# 文字列を3回送る
for i in range(3):
a.send("abcd")
if __name__ == "__main__":
sends = Process(target=send, args=(a,))
sends.start()
# 受信処理を遅延
time.sleep(5)
# pipeの受信と表示(ない場合はpass)
if b.poll() is True:
while b.poll() is True:
mai_list.append(b.recv())
print(mai_list)