为什么我在Mac上一段时间后就不再接收OSC消息了
本文关键字:不再 OSC 消息 Mac 一段时间 为什么 | 更新日期: 2023-09-27 18:21:21
我正在开发一款Unity游戏,该游戏从Muse EEG耳机接收OSC消息。我已经尝试了两个第三方C#库来处理OSC通信,UnityOSC
和unity-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进程或线程(垃圾收集?),因为无论我尝试什么,问题发生前的时间似乎都是恒定的。但我不确定如何进一步诊断,更不用说现在就解决这个问题了。任何线索、建议或惊人的解决方案都将是最受欢迎的。
我找到了原因。
在生成I/O进程之后,线程将执行
print("Process started!");
process.PriorityClass = ProcessPriorityClass.High;
process.WaitforExit();
事后看来,这份印刷声明的位置真的很糟糕,哦,好吧。它在Windows上运行良好。根据文档,更改流程优先级只需要管理员权限,如果您将其增加到实时。但在Mac上并非如此。显然,将其设置为High还需要在OSX上提升权限。产生的异常是静默/未检测到/未捕获的,因为它发生在主线程之外。
然后,几分钟后,线程似乎被垃圾回收了,包括它的子进程,尽管它仍在运行。那次延误真的让我很失望,让我在所有错误的地方寻找原因。
经验教训:
- 多线程时要更加小心可能出现的异常
- 如果不是绝对必须的话,不要打乱流程优先级
- 永远不要相信医生