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
ueshita
September 15, 2018
2
8k
UnmanagedThreadノススメ
2018.09.15
Unity非同期完全に理解した勉強会
ueshita
September 15, 2018
Tweet
Share
More Decks by ueshita
See All by ueshita
こわくない!! たのしい!! GDExtension
ueshita
0
1.1k
Godot Engine完全に理解したかった
ueshita
1
450
Unityで3Dツールを作って開発を加速する
ueshita
3
3.3k
EmscriptenのOpenGLと純粋なWebGLと共存させる黒魔術
ueshita
1
4.3k
asm.js 減量やってみた
ueshita
0
810
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
PRO
301
110k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
1
3.4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
1
1.3k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
16
1.4k
The Language of Interfaces
destraynor
151
23k
Designing Experiences People Love
moore
136
23k
A designer walks into a library…
pauljervisheath
199
23k
The Cult of Friendly URLs
andyhume
74
5.7k
Web Components: a chance to create the future
zenorocha
305
41k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
20
1.6k
The Brand Is Dead. Long Live the Brand.
mthomps
48
28k
The Invisible Customer
myddelton
114
12k
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 を返す ➡ 現在のスレッドがマネージドかアンマネージドか をチェックすることが可能。