Upgrade to Pro — share decks privately, control downloads, hide ads and more …

UnmanagedThreadノススメ

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for ueshita ueshita
September 15, 2018
8.3k

 UnmanagedThreadノススメ

2018.09.15
Unity非同期完全に理解した勉強会

Avatar for ueshita

ueshita

September 15, 2018
Tweet

Transcript

  1. UnmanagedThreadノススメ 諸注意 • オススメしないです。 • 本 LT は Hack に近いことをやります。

    • 各バージョン、各ターゲットで問題なく動 作することは保証しません。 • 参考にされる方は自己責任でがんばっ てください。
  2. UnmanagedThreadノススメ マネージドスレッド • Mono (.NET) が管理しているスレッド。 • [C#] Thread クラス

    , Task.Run (Thread Pool) 等。 • GC に影響される( Full GC が走ると一時停止)。 • (Unity や Mono からすると ) 安全なスレッド。
  3. UnmanagedThreadノススメ アンマネージドスレッド • Mono が管理していないスレッド ◦ [Win32] CreateThread ◦ [POSIX]

    pthread_create • GC に影響されない。 Full GC が走っても動き続ける。 • (Unity や Mono からすると ) ちょっと危ないスレッド
  4. UnmanagedThreadノススメ OnAudioFIlterRead(float[] data, int channels) 再生中のオーディオをリアルタイムに編集できるイベント関数 Unity スクリプトリファレンスから一部抜粋 https://docs.unity3d.com/ja/current/ScriptReference/MonoBehaviour.OnAudioFilterRead.html また、

    OnAudioFilterRead は メインスレッドとは別のスレッド(つまりオーディオス レッド)で呼び出されるので、この関数から多くの Unity 関数を呼び出すことはで きません(実行時に警告が表示される)。
  5. UnmanagedThreadノススメ MonoThread* mono_thread_attach(MonoDomain* domain) アンマネージドスレッドをマネージドスレッド化する関数 これを呼び出したスレッドは、以降 Mono に管理される。 内部的には TLS(Thread

    Local Storage) に マネージドスレッド的なコンテキストが埋め込まれている模様 MonoDomain* は mono_domain_get() で取得したものを指定。
  6. UnmanagedThreadノススメ Mono APIを取ってくる [Windows] LoadLibrary(“mono.dll”) して GetProcAddress(“mono_thread_attach”) [macOS] libmono.0.dylib をプラグインにリンクして使用。

    [Android] dlopen(“libmono.so”) して dlsym(“mono_thread_attach”) でシンボルを取得 [iOS/WebGL] Internal 関数なので extern で宣言して使用 extern “C” MonoThread* mono_thread_attach(MonoDomain* domain);
  7. UnmanagedThreadノススメ 懸念点 • mono_thread_attach() / mono_thread_detach() の 実行負荷は? • attach

    ~ detach の間は普通に GC に捕まるよね。 • やっぱり Unity オブジェクトは触れないので 使いどころは限られる。
  8. UnmanagedThreadノススメ (オマケ) MonoThread* mono_thread_current() 現在のスレッドの MonoThread* を返す - マネージドスレッドから呼び出す :

    MonoThread* を返す - アンマネージドスレッドから呼び出す : NULL を返す ➡ 現在のスレッドがマネージドかアンマネージドか をチェックすることが可能。