Почему я перестаю получать сообщения OSC через некоторое время на Mac?

Я работаю над игрой Unity, которая получает сообщения OSC от гарнитуры Muse EEG. Я попробовал две сторонние библиотеки C# для обработки связи OSC, UnityOSC и unity-OSC-receiver. Оба реализуют связь OSC с базовым System.Net.Sockets.UdpClient. В Windows все работает гладко, но в OSX через некоторое время я просто перестаю получать сообщения каждый раз. Никаких исключений или сообщений об ошибках, никаких указаний на то, что вообще пошло не так, просто тишина.

Мое приложение примерно работает следующим образом:

  • Запустите поток, который порождает процесс, запускающий Muse-IO. Это заставляет гарнитуру начать отправлять сообщения. После запуска процесса эта ветка просто остывает на process.WaitforExit()
  • Другой поток выполняет цикл while — не в MonoBehavior.Update(), это недостаточно быстро — который продолжает получать и обрабатывать сообщения OSC. В обеих библиотеках это по существу сводится к вызову UdpClient.Receive()
  • Игра использует обработанные сообщения в обычном цикле обновления Unity.

Где-то через 120-140 секунд после инициализации соединения поток сообщений просто останавливается, и пока я не смог понять, почему. Индикатор подключения на гарнитуре продолжает гореть, но ничего не указывает на то, что она все еще отправляет данные.

Вещи, которые я исключил:

  • Дело не в количестве сообщений или размере сообщений. Если я изменю команду для гарнитуры, чтобы отправлять только некоторые категории сообщений, сократив общее количество сообщений вдвое (примерно с 600/с до 300/с), тайм-аут все равно произойдет в то же время.
  • Это не библиотека OSC. Я получаю одинаковые результаты с обеими библиотеками OSC.
  • Это не брандмауэр. Брандмауэр выключен.
  • Вероятно, это не порт, используемый чем-то другим. Я пробовал разные порты с тем же результатом.
  • Похоже, это не драйвер Muse OSX. Когда я использую их графический интерфейс для визуализации входящих данных, он продолжает получать данные столько, сколько я хочу.

Я подозреваю, что Mono, Unity или OSX могут останавливать (сборщик мусора?) процесс или поток Muse-IO, потому что время до возникновения проблемы кажется в значительной степени постоянным, независимо от того, что я пытаюсь сделать. Но я не уверен, как дальше диагностировать, не говоря уже о том, чтобы исправить это сейчас. Любые подсказки, предложения или удивительные решения будут приветствоваться.


person Junuxx    schedule 10.11.2015    source источник
comment
Я понимаю, что это очень специфическая/узкая проблема, но я очень надеюсь, что кто-нибудь сможет мне помочь. Я собираюсь разместить награду, как только смогу.   -  person Junuxx    schedule 11.11.2015
comment
Ну, решил. Я опубликовал решение на случай, если кто-то когда-нибудь столкнется с подобной проблемой, но я думаю, что в конце концов вознаграждения не будет.   -  person Junuxx    schedule 12.11.2015


Ответы (1)


Я нашел причину.

После запуска процесса ввода-вывода поток будет выполнять

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

Оглядываясь назад, можно сказать, что это утверждение печати действительно неудачно, да ладно. Он отлично работал в Windows. Для изменения приоритета процесса требуются права администратора, только если вы увеличиваете его до Realtime, согласно документации. Однако не так на Mac. по-видимому, для установки высокого уровня также требуются повышенные права в OSX. Результирующее исключение было тихим/необнаруженным/неперехваченным, потому что оно происходит вне основного потока.

Затем, через несколько минут, кажется, что поток убирается сборщиком мусора, включая его дочерний процесс, хотя он все еще работает. Эта задержка действительно сбила меня с толку, заставив искать причину не в тех местах.

Уроки выучены:

  • Будьте внимательнее с возможными исключениями при многопоточности,
  • Не связывайтесь с приоритетом процесса, если в этом нет абсолютной необходимости,
  • И никогда не доверяйте документам.
person Junuxx    schedule 12.11.2015