开发者社区> 问答> 正文

两个协程使用asyncio同时运行

我正在尝试制作一个程序,该程序可以读取数据以及通过websocket从服务器发送和接收数据。目标是创建同步灯,其中有两个客户端灯和一个服务器。当其中一个灯更改状态时,它将向服务器发送请求,而服务器会更新另一个灯。我目前停留在客户端代码上。我可以与服务器建立Websocket连接,读取数据并将其发送到服务器,并且可以读取轻量数据。我在同时运行这两个任务时遇到问题。我想异步执行此操作以避免竞争条件问题。我正在使用python 3.8和asyncio。

到目前为止,这是我的websocket客户端代码:

async def init_connection(message):
  global CONNECTION_OPEN
  global CLIENT_WS
  uri = WS_URI
  async with websockets.connect(uri) as websocket:
      CONNECTION_OPEN = True
      CLIENT_WS = websocket
      # send init message
      await websocket.send(message)
      while CONNECTION_OPEN:
          await handleMessages(websocket, message)
      await websocket.send(json.dumps({'type': MessageType.Close.name, 'message': USERNAME}))
      await websocket.close()

到目前为止,这是我读到的数据代码:

async def calculate_idle(t):
  global STATE
  global prevColor
  x_arr = []
  y_arr = []
  z_arr = []
  while t >= 0:
     x, y, z = lis3dh.acceleration
     print("Current colors")
     print(accel_to_color(x,y,z))
     x_arr.append(x)
     y_arr.append(y)
     z_arr.append(z)
     newColor = accel_to_color(x,y,z)
     # remember prev color
     do_fade(prevColor, newColor)
     #strip.fill((int(a_x), int(a_y), int(a_z), 0))
     #strip.show()
     prevColor = newColor
     time.sleep(.2)
     t -= .2
  is_idle = is_lamp_idle(np.std(x_arr), np.std(y_arr), np.std(z_arr))

  if is_idle and STATE == "NOT IDLE" and CONNECTION_OPEN:
      STATE = "IDLE"
      print("Sending color")
      await asyncio.sleep(1)
  elif is_idle and CONNECTION_OPEN:
      # Check for data
      STATE = "IDLE"
      print ("Receiving data")
      await asyncio.sleep(1)
  elif is_idle and not CONNECTION_OPEN:
     print ("Idle and not connected")
      rainbow_cycle(0.001)    # rainbow cycle with 1ms delay per step
      await asyncio.sleep(1)
  else:
      STATE = "NOT IDLE"
      await asyncio.sleep(1)
      print("Is not idle")

这是应该将它们捆绑在一起的代码:

async def main():
    message = json.dumps({'type': "authentication", 'payload': {
                            'username': 'user1', 'secret': SHARED_SECRET}})
    loop = asyncio.get_event_loop()
    start_light = asyncio.create_task(calculate_idle(3))
    await asyncio.gather(init_connection(message), start_light)
asyncio.run(main())

还有其他功能,但前提是存在一个用于发送和接收数据的websocket连接,以及另一个读取轻量数据的进程。我还需要能够读取灯光的当前状态并设置灯光的当前状态,这就是我使用全局变量的原因。当前,它将读取灯光,直到它在计算空闲时碰到一个等待asyncio.sleep(1),然后切换到websocket代码并挂起从服务器接收数据。理想情况下,它将在读取当前状态和检查Websocket消息之间交替进行。如果状态发生变化,它将发送一个websocket消息。

如何才能异步运行这两个例程并在它们之间共享数据?任何帮助表示赞赏!

问题来源:stackoverflow

展开
收起
is大龙 2020-03-24 12:11:03 1052 0
1 条回答
写回答
取消 提交回答
  • 感谢user4815162342的评论,以帮助缩小问题范围。我的计算空闲时间没有那么长,我将time.sleep(.2)更改为等待asyncio.sleep(.2),我能够同时从服务器和电灯中读取数据。

    回答来源:stackoverflow

    2020-03-24 12:11:09
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Swoole2.0原生协程高性能开发实践 立即下载
fibjs 模块重构从回调到协程 立即下载
fibjs 模块重构从回调到协程--陈垒 立即下载