Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
UnmanagedThreadノススメ
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ueshita
September 15, 2018
8.4k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
UnmanagedThreadノススメ
2018.09.15
Unity非同期完全に理解した勉強会
ueshita
September 15, 2018
More Decks by ueshita
See All by ueshita
こわくない!! たのしい!! GDExtension
ueshita
0
2.2k
Godot Engine完全に理解したかった
ueshita
1
670
Unityで3Dツールを作って開発を加速する
ueshita
3
3.7k
EmscriptenのOpenGLと純粋なWebGLと共存させる黒魔術
ueshita
1
5.1k
asm.js 減量やってみた
ueshita
0
1k
Featured
See All Featured
Side Projects
sachag
455
43k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Believing is Seeing
oripsolob
1
170
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
390
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
260
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
260
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
450
The Curious Case for Waylosing
cassininazir
1
430
Typedesign – Prime Four
hannesfritz
42
3.1k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
190
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Transcript
UnmanagedThreadノススメ 2018.09.15 Unity 非同期完全に理解した勉強会 うえした (@ueshita)
UnmanagedThreadノススメ 諸注意 • オススメしないです。 • 本 LT は Hack に近いことをやります。
• 各バージョン、各ターゲットで問題なく動 作することは保証しません。 • 参考にされる方は自己責任でがんばっ てください。
UnmanagedThreadノススメ LTのテーマ (やりたいこと)
UnmanagedThreadノススメ やりたいこと ネイティブプラグインで 作成したスレッドから、 C#の関数を呼び出したい!
UnmanagedThreadノススメ ネイティブプラグインで 作成したスレッド アンマネージドスレッド
UnmanagedThreadノススメ What’s Unmanaged Thread?
UnmanagedThreadノススメ その前に マネージドスレッド
UnmanagedThreadノススメ マネージドスレッド • Mono (.NET) が管理しているスレッド。 • [C#] Thread クラス
, Task.Run (Thread Pool) 等。 • GC に影響される( Full GC が走ると一時停止)。 • (Unity や Mono からすると ) 安全なスレッド。
UnmanagedThreadノススメ アンマネージドスレッド
UnmanagedThreadノススメ アンマネージドスレッド • Mono が管理していないスレッド ◦ [Win32] CreateThread ◦ [POSIX]
pthread_create • GC に影響されない。 Full GC が走っても動き続ける。 • (Unity や Mono からすると ) ちょっと危ないスレッド
UnmanagedThreadノススメ 危ない? ちょっと危ないアンマネージドスレッドから マネージド関数を呼び出してもいいの? • 最悪死に至る (?) • Editor のデバッガが不安定になる
(?) • 呼べても Unity の GameObject や コンポーネントに触れないよ!
UnmanagedThreadノススメ 安全に呼べないの?
UnmanagedThreadノススメ そういえばUnity標準機能の中に… アンマネージドスレッドから マネージド関数を 呼んでいたやつが居た気がする
UnmanagedThreadノススメ MonoBehaviour.OnAudioFIlterRead
UnmanagedThreadノススメ OnAudioFIlterRead(float[] data, int channels) 再生中のオーディオをリアルタイムに編集できるイベント関数 Unity スクリプトリファレンスから一部抜粋 https://docs.unity3d.com/ja/current/ScriptReference/MonoBehaviour.OnAudioFilterRead.html また、
OnAudioFilterRead は メインスレッドとは別のスレッド(つまりオーディオス レッド)で呼び出されるので、この関数から多くの Unity 関数を呼び出すことはで きません(実行時に警告が表示される)。
UnmanagedThreadノススメ オーディオスレッドは GCによって一時停止してはいけない (リアルタイム音声処理が途切れる) OnAudioFilterReadは アンマネージドスレッド から呼び出されているハズ
UnmanagedThreadノススメ Unityはどうやって アンマネージドスレッドから 安全にマネージド関数を 呼んでいるのか
UnmanagedThreadノススメ Unity の お気持ち を考えよう (いつもの)
UnmanagedThreadノススメ そもそも Mono の領域なのでは
UnmanagedThreadノススメ Mono の お気持ち を理解しよう
UnmanagedThreadノススメ Monoのお気持ちを理解する Unity は Mono の上で構築されている。 Mono のお気持ちを理解することが Unity のお気持ちの理解に繋がる!
Mono のお気持ちの全て↓ https://github.com/mono/mono Mono
UnmanagedThreadノススメ よくわかるMonoのお気持ち Embedding Mono https://www.mono-project.com/docs/advanced/embedding/ Mono ランタイムを みんなのアプリに組み込むためのドキュメント この仕組み上で Unity
が構築されているよ(たぶん)
UnmanagedThreadノススメ アンマネージドスレッド に関する情報を探す
UnmanagedThreadノススメ Threading Issuesのところを見る ( 和訳 ) アプリケーションが独自にスレッドを作成し、それらを Mono とやり取りできるようにするには、そのスレッドを登録してランタイム がそのスレッドを認識できるようにする必要があります。
これを行うには、他の Mono API を実行する前に、または管理オブ ジェクトを操作する前に、 mono_thread_attach() 関数を呼び出し ます。
UnmanagedThreadノススメ あー mono_thread_attach() ね Unity,Mono完全に理解した
UnmanagedThreadノススメ MonoThread* mono_thread_attach(MonoDomain* domain) アンマネージドスレッドをマネージドスレッド化する関数 これを呼び出したスレッドは、以降 Mono に管理される。 内部的には TLS(Thread
Local Storage) に マネージドスレッド的なコンテキストが埋め込まれている模様 MonoDomain* は mono_domain_get() で取得したものを指定。
UnmanagedThreadノススメ せっかく作った アンマネージドスレッド がマネージドスレッドに なってしまう?
UnmanagedThreadノススメ そこで mono_thread_detach()
UnmanagedThreadノススメ void mono_thread_detach(MonoThread *thread) マネージドスレッドをアンマネージドスレッドに 戻してやる Mono API MonoThread* で指定したマネージドスレッドは
Mono の管理対象から外れる ➡ Full GC の影響を受けなくなる!
UnmanagedThreadノススメ 基本戦略 (1) mono_thread_attach() を呼ぶ (2) C# のマネージド関数 ( デリゲート
) を呼ぶ (3) mono_thread_detach() を呼ぶ
UnmanagedThreadノススメ Mono APIをどうにかして ネイティブプラグインから呼び出す
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);
UnmanagedThreadノススメ ターゲットごとにブランチ (#ifdef地獄つらい)
UnmanagedThreadノススメ そして様々な 苦難を乗り越え…(?)
UnmanagedThreadノススメ とりあえず動いたよ Debug.Log() は普通に呼べるっぽいです。
UnmanagedThreadノススメ 懸念点 • mono_thread_attach() / mono_thread_detach() の 実行負荷は? • attach
~ detach の間は普通に GC に捕まるよね。 • やっぱり Unity オブジェクトは触れないので 使いどころは限られる。
UnmanagedThreadノススメ ネイティブプラグイン沼はたのしい (おわり)
UnmanagedThreadノススメ (オマケ) MonoThread* mono_thread_current() 現在のスレッドの MonoThread* を返す - マネージドスレッドから呼び出す :
MonoThread* を返す - アンマネージドスレッドから呼び出す : NULL を返す ➡ 現在のスレッドがマネージドかアンマネージドか をチェックすることが可能。