質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

2727閲覧

画像をwebsocketでサーバに送信している間に非同期で撮影の処理を行いたい。

chekke1999

総合スコア21

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/01/22 03:27

編集2021/02/10 02:24

題名のとおり、画像データをサーバに送信中に非同期で撮影をさせたいです。
以下のように_shoot()が撮影したデータを_Send()に渡して送信させているのですが、非同期になりません。
await asyncio.Task()を複数なれべれば非同期になってくれるわけではないのですか?

Python3

1import asyncio,json,websockets,os,time,atexit,io,base64,socket,struct,serial 2import fcntl,struct,uuid,re,cv2 3import numpy as np 4import netifaces as ni 5import scapy.all as scapy 6import netifaces as ni 7from screeninfo import get_monitors 8from sys import argv 9 10from PIL import Image 11from jsongen import genjson 12 13monitor = get_monitors()[0] 14def imshow_fullscreen(winname, img): 15 cv2.namedWindow(winname, cv2.WINDOW_NORMAL) 16 cv2.setWindowProperty(winname, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) 17 cv2.imshow(winname, img) 18 cv2.waitKey(300) 19def resize(img,re_length): 20 h, w = img.shape[:2] 21 re_h = re_w = re_length/min(h,w) 22 img2 = cv2.resize(img, dsize=None, fx=re_h , fy=re_w) 23 return img2 24def full_img(): 25 cap = cv2.VideoCapture (0) 26 WIDTH = 4056 27 HEIGHT = 3040 28 cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('Y','U','1','2')) 29 cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) 30 cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT) 31 _, frame = cap.read() 32 imshow_fullscreen('screen', resize(frame,monitor.height)) 33 return cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 34 35async def _Send(url,jlist): 36 async with websockets.connect(url,max_size=20000000) as websocket: 37 start = time.time() 38 sendj = json.dumps(jlist) 39 await websocket.send(sendj) 40 try: 41 recv_data = await websocket.recv() 42 except Exception as e: 43 print("websockets.exceptions.ConnectionClosedError:",e) 44 print('Reconnecting') 45 websocket = await websockets.connect(url,max_size=20000000) 46 await websocket.send(sendj) 47 else: 48 print("Send complete successfully:",time.time() - start,"[sec]") 49 print ("return:",recv_data) 50class CamPi: 51 @classmethod 52 async def _shoot(cls): 53 start = time.time() 54 png = io.BytesIO() 55 print("Please wait until the shooting is completed...",end="") 56 Image.fromarray(full_img()).save(png,"PNG") 57 print("\rshooting complete successfully:",time.time() - start,"[sec]") 58 b_frame = png.getvalue() 59 send_d = { 60 "in_data" : { 61 "db":"piscan", 62 "mac":"58:52:8a:d6:69:a1", 63 "jstr":genjson(), 64 "img":[base64.b64encode(b_frame).decode('utf-8'),base64.b64encode(b_frame).decode('utf-8')] 65 } 66 } 67 return send_d 68 @classmethod 69 async def Main(cls): 70 while(True): 71 start = time.time() 72 send_d = await asyncio.Task(cls._shoot()) 73 await asyncio.Task(_Send("ws://192.168.11.199:8080",send_d)) 74 print("End of loop time:",time.time() - start,"[sec]") 75 #time.sleep(10) 76 77 78if __name__ == '__main__': 79 if argv[1] == "-c": 80 asyncio.run(CamPi.Main())

追記

解決したわけではありませんが、結局multiProcessingでやりたいことは実現しました。でも非同期でのやりかたが結局わからないままなので質問は残しておきます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

await asyncio.Task()を複数なれべれば非同期になってくれるわけではないのですか?

はい。
asyncio.Taskオブジェクト作成するだけでは不十分で、実行環境が提供するイベントループに、そのタスクを登録する必要があります。

その他例外機構や実行環境との調整等が必要なこともあり、Taskオブジェクトを直接作成することは、公式に非推奨とされています。

Taskオブジェクト:class asyncio.Task

Task を作成するには高レベルの asyncio.create_task() 関数、あるいは低レベルの loop.create_task() 関数や ensure_future() 関数を使用してください。 手作業での Task の実装は推奨されません。

diff

1 async def Main(cls): 2 while(True): 3 start = time.time() 4- send_d = await asyncio.Task(cls._shoot()) 5+ send_d = await cls._shoot() 6- await asyncio.Task(_Send("ws://192.168.11.199:8080",send_d)) 7+ asyncio.create_task(_Send("ws://192.168.11.199:8080",send_d)) 8 print("End of loop time:",time.time() - start,"[sec]") 9 #time.sleep(10)

投稿2021/01/22 03:49

編集2021/01/22 03:54
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chekke1999

2021/01/22 04:55

書き換えて実行してみましたが、asyncio.create_task(_Send("ws://192.168.11.199:8080",send_d)) だけだと送信されませんでした。頭にawaitをつけたら動きますが、送信中に撮影をしてくれず、非同期になりませんでした。
guest

0

どっちかいうと、画像をwebsocketでサーバに送信するほうを非同期で行いましょうよ

投稿2021/01/22 03:29

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chekke1999

2021/01/22 04:48

そうしたいんですけど、送信だけ非同期で、撮影は同期ってどうやって書けばいいんでしょう?
退会済みユーザー

退会済みユーザー

2021/01/23 01:16

asyncで定義してやって そのあとに定義したやつを呼び出すと非同期で動くようになります 呼び出したあとに書いたらそのコードは同期なので書くのは簡単です
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問