为什么我在Mac上一段时间后就不再接收OSC消息了

本文关键字:不再 OSC 消息 Mac 一段时间 为什么 | 更新日期: 2023-09-27 18:21:21

我正在开发一款Unity游戏,该游戏从Muse EEG耳机接收OSC消息。我已经尝试了两个第三方C#库来处理OSC通信,UnityOSCunity-OSC-receiver。两者都实现了与底层CCD_ 3的OSC通信。在Windows上一切都运行得很顺利,但在OSX上,过了一段时间,我就不再每次接收消息了。没有异常或错误消息,根本没有出现问题的迹象,只是保持沉默。

我的应用程序大致工作如下:

  • 启动一个线程,该线程生成一个运行Muse IO的进程。这会使耳机开始发送信息。启动进程后,此线程只是在process.WaitforExit()上冷却
  • 另一个线程运行while循环(不在MonoBehavior.Update()中,这还不够快),该循环保持接收和处理OSC消息。在这两个库中,这基本上可以归结为调用UdpClient.Receive()
  • 游戏在正常的Unity更新周期中使用已处理的消息

在连接初始化大约120到140秒后,消息流就停止了,到目前为止我还不知道为什么。耳机上的连接指示灯一直亮着,但没有任何迹象表明它实际上仍在发送数据。

我已经排除的事情:

  • 这并不是因为消息的数量或大小。如果我修改耳机的命令,只发送某些类别的消息,将总数减半(从大约600/s减少到300/s),超时仍然会同时发生
  • 这不是OSC图书馆。我用两个OSC库得到了完全相同的结果
  • 这不是防火墙。防火墙已关闭
  • 它可能不是其他人使用的端口。我尝试了不同的端口,结果相同
  • 它似乎不是Muse的OSX驱动程序。当我使用他们的GUI来可视化传入的数据时,它会在我想要的时间内不断接收数据

我怀疑Mono、Unity或OSX可能会关闭Muse IO进程或线程(垃圾收集?),因为无论我尝试什么,问题发生前的时间似乎都是恒定的。但我不确定如何进一步诊断,更不用说现在就解决这个问题了。任何线索、建议或惊人的解决方案都将是最受欢迎的。

为什么我在Mac上一段时间后就不再接收OSC消息了

我找到了原因。

在生成I/O进程之后,线程将执行

print("Process started!");
process.PriorityClass = ProcessPriorityClass.High;
process.WaitforExit();

事后看来,这份印刷声明的位置真的很糟糕,哦,好吧。它在Windows上运行良好。根据文档,更改流程优先级只需要管理员权限,如果您将其增加到实时。但在Mac上并非如此。显然,将其设置为High还需要在OSX上提升权限。产生的异常是静默/未检测到/未捕获的,因为它发生在主线程之外。

然后,几分钟后,线程似乎被垃圾回收了,包括它的子进程,尽管它仍在运行。那次延误真的让我很失望,让我在所有错误的地方寻找原因。

经验教训:

  • 多线程时要更加小心可能出现的异常
  • 如果不是绝对必须的话,不要打乱流程优先级
  • 永远不要相信医生