SlideShare une entreprise Scribd logo
1  sur  80
非同期処理の
基礎知識
岩永 信之
今日話すこと
• 非同期処理がらみの良い書き方/悪い書き方
• それがなぜ良い/悪い
• 突き詰めるとCPUやOSレベルの話に
非同期処理の書き方
良い例・悪い例を紹介
先に事例紹介(良い・悪い理由は後ほど)
ThreadよりもTask
for (int i = 0; i < num; i++)
{
var t = new Thread(_ =>
b[i] = F(a[i])
);
}
for (int i = 0; i < num; i++)
{
Task.Run(() =>
b[i] = F(a[i])
);
}
×悪い例
○良い(まだマシ※な)例
データの数だけ
スレッド作成
Threadでなく
Task利用
※ この場合、ParallelクラスやParallel.Enumerableクラスが使いやすい
ThreadよりもTask
for (int i = 0; i < num; i++)
{
var t = new Thread(_ =>
b[i] = F(a[i])
);
}
for (int i = 0; i < num; i++)
{
Task.Run(() =>
b[i] = F(a[i])
);
}
×悪い例
○良い(まだマシ※な)例
データの数だけ
スレッド作成
Threadでなく
Task利用
※ この場合、ParallelクラスやParallel.Enumerableクラスが使いやすい
題材
• スレッドのコスト
• スレッド プール
非同期I/O
using (var r = new StreamReader("some.txt"))
{
var t = r.ReadToEndAsync();
Console.WriteLine(await t);
}
using (var r = new StreamReader("some.txt"))
{
var t = Task.Run(() => r.ReadToEnd());
Console.WriteLine(await t);
}
Task.Run
+
同期I/O
非同期I/O用メソッド
×悪い例
○良い例
非同期I/O
using (var r = new StreamReader("some.txt"))
{
var t = r.ReadToEndAsync();
Console.WriteLine(await t);
}
using (var r = new StreamReader("some.txt"))
{
var t = Task.Run(() => r.ReadToEnd());
Console.WriteLine(await t);
}
Task.Run
+
同期I/O
非同期I/O用メソッド
×悪い例
○良い例
題材
• CPU-boundとI/O-bound
• I/O完了ポート
データ競合
var count = 0;
Parallel.For(0, num, i =>
{
++count;
});
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
期待通りに動かない
count == numにならない
lockをかけるととりあえず
期待通りにはなる
×悪い例
○良い(まだマシ※な)例
※ Interlocked.Incrementメソッド使えばlockなしでスレッド安全にインクリメントできる
性能を考えると、次節のスレッド ローカルを使う方がいい
データ競合
var count = 0;
Parallel.For(0, num, i =>
{
++count;
});
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
期待通りに動かない
count == numにならない
lockをかけるととりあえず
期待通りにはなる
×悪い例
○良い(まだマシ※な)例
※ Interlocked.Incrementメソッド使えばlockなしでスレッド安全にインクリメントできる
性能を考えると、次節のスレッド ローカルを使う方がいい
題材
• 競合が起きる理由
• lock
スレッド ローカル
var count = 0;
Parallel.For(0, num,
() => 0,
(i, state, localCount) => localCount + 1,
localCount => count += localCount
);
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
×悪い例
○良い例
(さっきの「マシな例」)
lockしてスレッド間で同じ
データを読み書き
スレッドごとに別計算
最後に集計
スレッド ローカル
var count = 0;
Parallel.For(0, num,
() => 0,
(i, state, localCount) => localCount + 1,
localCount => count += localCount
);
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
×悪い例
○良い例
(さっきの「マシな例」)
lockしてスレッド間で同じ
データを読み書き
スレッドごとに別計算
最後に集計
題材
• スレッド並列
• 並列化しやすいアルゴリズム
イベントの実装(前置き)
event EventHandler Disposed; 自動実装イベント
event EventHandler Disposed
{
add { _disposed += value; }
remove { _disposed -= value; }
}
private EventHandler _disposed;
こんな意味合いのコードに対し
て、
「スレッド安全」が求められる
(C#の規格上そう定めてある)
C#のイベント
「自動実装」の結果 (意味的には)
イベントの実装
[MethodImpl(MethodImplOptions.Synchronized)]
add { _disposed += value; }
lock (this)相当
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, va
disposed = Interlocked.CompareExchange(ref _disposed, hand
}
while (disposed != handler2);
}
×C# 3.0までの実装(悪い例)
○C# 4.0以降の実装(良い例)
lock-free※アルゴリズム
※ lockを使わずに競合を避けること
イベントの実装
[MethodImpl(MethodImplOptions.Synchronized)]
add { _disposed += value; }
lock (this)相当
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, va
disposed = Interlocked.CompareExchange(ref _disposed, hand
}
while (disposed != handler2);
}
×C# 3.0までの実装(悪い例)
○C# 4.0以降の実装(良い例)
題材
• interlocked命令
• lock-freeアルゴリズム
lock-free※アルゴリズム
※ lockを使わずに競合を避けること
基礎
今の事例はいったん置いておいて
CPUとかOSレベルの話を
CPU
まず、CPUの動作について
CPU = 演算回路+記憶領域
ALU
メイン・メモリ
データを格納
高速・小容量
加減乗除などの
演算を実行†
データを格納
低速・大容量
† arithmetic logic unit
演算回路記憶領域
CPU = 演算回路+記憶領域
ALU
メイン・メモリ
記憶領域には階層がある
高速小容量 ⇔ 低速大容量
演算回路と直接つながってるのは、
1番高速で、1番小容量の記憶
CPUの動作例
• 高級言語的に1ステートメントでも…
ALU
メイン・メモリ
++count;
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
C#
CPU命令
コンパイル
CPUの動作例
① 読み込み
ALU
メイン・メモリ
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
++count;
C#
CPU命令
コンパイル
CPUの動作例
② 演算
ALU
メイン・メモリ
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
+1
++count;
C#
CPU命令
コンパイル
CPUの動作例
③ 書き出し
ALU
メイン・メモリ
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
++count;
C#
CPU命令
コンパイル
CPUの動作例
③ 書き出し
ALU
メイン・メモリ
① mov eax, [04D74010h]
② inc eax
③ mov [04D74010h], eax
++count;
C#
CPU命令
コンパイル
ポイント
• 単純な処理でも複数命令からなる
• 読み込み、演算、書き出し
• 上から順に逐次実行
注意: 読み込みの原子性※
ALU
メイン・メモリ
64bit データ
ALU
メイン・メモリ
データ64bit
※ atomicity: 不可分性。中途半端な不正な状態を起こさないこと
64bit CPUの場合 32bit CPUの場合
1命令完結 2命令必要
命令と命令の間に割り込まれると
データが半分しか読まれてない状態になる
割り込み
CPUと、CPUの外の世界(ハードウェア割り込み)
特権モード(ソフトウェア割り込み)
CPUの外の世界
• 当然、CPUだけでは何もできない
ALU
メイン・メモリ
CPU 周辺機器
割り込み信号
割り込み
• 外部ハードウェアから「割り込み信号」が来る
• 信号を受け取ると、実行中の処理を止めて、いった
ん別処理をする
命令列
別の処理
外部ハードウェアから
の信号を受け取って、
処理を中断
再開
mov eax, [04D74010h]
inc eax
mov [04D74010h], eax
……
割り込みタイミング
• 割り込みはどこでかかるかわからない
mov eax, [04D74010h]
inc eax
mov [04D74010h], eax
……
ここで割り込まれる
かもしれないし
ここも
ここも
ここもありえる
ハードウェア タイマー
• 一定間隔で割り込み信号を送ってくるハード
ウェアがある
• スレッドで使う(詳細は後述)
命令列
ハードウェアタイマー
割り込み
割り込み
割り込み
…
別の処理
別の処理
別の処理
ソフトウェア割り込み
• 割り込み命令
命令列
別の処理
自分自身で割り込みを
起こせる命令がある
再開
割り込み発生命令
……
モード切り替え
• 何に使うかというと、モード切り替え
命令列
別の処理割り込み発生命令
……
通常のセキュリティ
レベルで動作
特権的なセキュリティ
レベルで動作
異なるモードで動作
特権モード
ユーザー モード
• 一般のプログラ
ムに認められる
セキュリティ レ
ベル
• アクセスできる
メモリに制限が
ある
特権モード※
• OSが使うセキュ
リティ レベル
• 制限がかからな
い
モード移行にはそれなりのコストが発生
※ OSのカーネルが使うんで、カーネル モード(kernel mode)ともいう
CPUの高度化
キャッシュ メモリ
マルチコアCPU
• 記憶領域の階層は多段
メイン メモリ
2次キャッシュ メモリ
キャッシュ
ALU
キャッシュ メモリ
高速
小容量
低速
大容量
速度差が大きすぎる
キャッシュ1段ごとに1桁くらい遅い
• 記憶領域の階層は多段
メイン メモリ
2次キャッシュ メモリ
キャッシュ
ALU
キャッシュ メモリ
高速
小容量
低速
大容量
このサイズに収まる範囲で
読み書きする分には高速
広範囲にデータを読み書き
すると、低速なメモリへの
読み書きが発生
• コアごとにキャッシュ持ってたり
メイン メモリ
2次キャッシュ メモリ
マルチコア
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
• コアで同じデータを読み書きすると
メイン メモリ
2次キャッシュ メモリ
マルチコア
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
同じブロックを読み書
きしているつもりでも 実際には別の場所にある
1段下(低速)に書き戻されて
ないと正しい値が取れない = 1桁遅い
• 非均一な読み書き速度
NUMA※
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
※ non-uniform memory access: 非均一なメモリアクセス
メモリ ノード1 メモリ ノード2 メモリ ノード3
高速
アクセスはできる
ものの、低速
• 非均一な読み書き速度
NUMA※
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
ALU
キャッシュ メモリ
※ non-uniform memory access: 非均一なメモリアクセス
メモリ ノード1 メモリ ノード2 メモリ ノード3
高速
アクセスはできる
ものの、低速
ポイント
• コアをまたいだデータ読み書きは
かなり低速
スレッド
マルチタスク
CPUのシェア
マルチタスク
• コンピューター内で複数のタスクが同時に動作
• CPUコア数に制限されない
タスク1 タスク2 タスク3 …
タスクの動作期間
実際にCPUを使って
動いている期間
1つのCPUコアを複数の
タスクがシェアしてる
問題は
• どうやって他のタスクにCPUを譲るか
• 誰がどうスケジューリングするか
2種類のマルチタスク
† preemptive: 専買権を持つ、横取りする
※cooperative
• ハードウェア タイマーを使って強制割り込み
• OSが特権的にスレッド切り替えを行う
• ○利点: 公平 (どんなタスクも等しくOSに制御奪われる)
• ×欠点: 高負荷 (切り替えコストと使用リソース量が多い)
プリエンプティブ†
• 各タスクが責任を持って終了する
• 1つのタスクが終わるまで次のタスクは始まらない
• ○利点: 低負荷
• ×欠点: 不公平 (1タスクの裏切りが、全体をフリーズさせる)
協調的※
なのでスレッドはこっち
これが致命的
ただ、問題はこれ
スレッドを立てるコスト※
• スレッドに紐づいたデータ
• カーネル ステート: 1kBくらい
• ローカル スタック: 1MBくらい
• イベント発生
• Thread Attached/Detachedイベント
※ Windowsの場合
スレッド切り替えコスト
• 直接的なコスト
• 特権モードへの移行・復帰
• レジスターの保存・復元
• 次に実行するスレッドの決定
• スレッドの状態を入れ替え
• 間接的なコスト
• キャッシュ ミス
どれも性能への
インパクト大きい
スレッドは高コスト
• 細々としたタスクを大量にこなすには向かない
for (int i = 0; i < 1000; i++)
{
var t = new Thread(Worker);
t.Start();
}
大量の処理をスレッド実行
リソース消費大
切り替え頻発
…
スレッド プール
• スレッドを可能な限り使いまわす仕組み
• プリエンプティブなスレッド数本の上に
• 協調的なタスク キューを用意
スレッド プール
キュー
タスク1
タスク2
…
数本※のスレッ
ドだけ用意
空いているスレッドを探して実行
(長時間空かない時だけ新規スレッド作成)
新規タスク
タスクは一度
キューに溜める
※ 理想的にはCPUのコア数分だけ
スレッド プールの性能向上
• Work Stealing Queue
• lock-free実装(後述)なローカル キュー
• できる限りスレッド切り替えが起きない作り
ローカル
キュー1
ローカル
キュー2
スレッド1 スレッド2
グローバル
キュー
①
スレッドごとに
キューを持つ
まず自分用の
キューからタスク実行
②
ローカル キュー
が空のとき、
他のスレッドから
タスクを奪取
スレッド プールの性能向上
• Work Stealing Queue
• lock-free実装(後述)なローカル キュー
• できる限りスレッド切り替えが起きない作り
ローカル
キュー1
ローカル
キュー2
スレッド1 スレッド2
グローバル
キュー
①
スレッドごとに
キューを持つ
まず自分用の
キューからタスク実行
②
ローカル キュー
が空のとき、
他のスレッドから
タスクを奪取
ポイント
• スレッドは高コスト
• Threadくらすはこっち
• スレッド プールの利用推奨
• Taskクラスはこっち
I/O完了ポート
外部ハードウェアからの応答を待つ
CPUの外の世界は遅い
• 実行速度が全然違う
ALU
メイン・メモリ
CPU 周辺機器
数千~
下手すると数万、数億倍遅い
2種類の負荷
• CPU-bound (CPUが性能を縛る)
• マルチコアCPUの性能を最大限引き出したい
• UIスレッドを止めたくない
• I/O-bound (I/O※が性能を縛る)
• ハードウェア割り込み待つだけ
• CPUは使わない
• スレッドも必要ない
※ Input/Output: 外部ハードウェアとのやり取り(入出力)
I/O完了待ち
• I/O-boundな処理にスレッドは不要
あるスレッド
要求
応答
この間何もしないのに
スレッドを確保し続け
るのはもったいない
I/O完了ポート※
• スレッドを確保せずI/Oを待つ仕組み
• コールバックを登録して、割り込みを待つ
• コールバック処理はスレッド プールで
スレッド プール
タスク1
タスク2
…
※ I/O completion port
あるスレッドアプリ
I/O完了ポート
ハードウェア
I/O開始 I/O完了
コールバック
登録
コールバック登録後、
すぐにスレッド上での
処理を終了
割り込み信号
I/O完了ポート※
• スレッドを確保せずI/Oを待つ仕組み
• コールバックを登録して、割り込みを待つ
• コールバック処理はスレッド プールで
スレッド プール
タスク1
タスク2
…
※ I/O completion port
あるスレッドアプリ
I/O完了ポート
ハードウェア
I/O開始 I/O完了
コールバック
登録
コールバック登録後、
すぐにスレッド上での
処理を終了
割り込み信号
ポイント
• I/O-boundな処理にスレッドを使っちゃダメ
• I/O用の非同期メソッドが用意されてる
(内部的にI/O完了ポートを利用)
事例に戻って
良い例・悪い例の理由
ThreadよりもTask
for (int i = 0; i < num; i++)
{
var t = new Thread(_ =>
b[i] = F(a[i])
);
}
for (int i = 0; i < num; i++)
{
Task.Run(() =>
b[i] = F(a[i])
);
}
×悪い例
○良い(まだマシ※な)例
データの数だけ
スレッド作成
Threadでなく
Task利用
※ この場合、ParallelクラスやParallel.Enumerableクラスが使いやすい
おさらい
• Threadクラス
• Windowsの生スレッド
• = プリエンプティブなマルチタスク
• 当然重たい
• 特権モード移行、レジスター退避、…
• Taskクラス
• スレッド プールを利用
• 必要な分だけスレッド使う
推奨
スレッドは生で使
うものじゃない
非同期I/O
using (var r = new StreamReader("some.txt"))
{
var t = r.ReadToEndAsync();
Console.WriteLine(await t);
}
using (var r = new StreamReader("some.txt"))
{
var t = Task.Run(() => r.ReadToEnd());
Console.WriteLine(await t);
}
Task.Run
+
同期I/O
非同期I/O用メソッド
×悪い例
○良い例
おさらい
• I/O-boundな処理のためにスレッドを専有し
ちゃダメ
• I/O完了ポート使う
• ハードウェアからの割り込みをイベント処理
• 標準ライブラリの~Async系のメソッドはこれを利
用
非推奨
Task.Run(() => r.ReadToEnd());
推奨
r.ReadToEndAsync();
おまけ: SleepよりもDelay
Task.Delay((int)(x * Scale))
.ContinueWith((_, state) =>
{
sorted.Enqueue((double)state);
}, x);
var t = new Thread(state =>
{
var value = (double)state;
Thread.Sleep((int)(value * Scale));
sorted.Enqueue(value);
});
t.Start(x);
スレッドを立ててから
Thread.Sleepで休止
Task.Delayで休止
×悪い例
○良い例
• 何もしないのにスレッド
を確保し続ける
• タイマー利用
(ハードウェア割り込み)
• スレッドを確保しない
データ競合
var count = 0;
Parallel.For(0, num, i =>
{
++count;
});
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
期待通りに動かない
count == numにならない
lockをかけるととりあえず
期待通りにはなる
×悪い例
○良い(まだマシ※な)例
※ Interlocked.Incrementメソッド使えばlockなしでスレッド安全にインクリメントできる
性能を考えると、次節のスレッド ローカルを使う方がいい
おさらい
• スレッドはハードウェア タイマーの割り込み
を使ってる
• 割り込みはいつかかるかタイミング不定
• 単純なコードでも、CPUレベルでは複数命令
++count;
C# CPU命令コンパイル
① 読み mov eax, [04D74010h]
② 計算 inc eax
③ 書き mov [04D74010h], eax
競合
• 複数のスレッドで同じ場所を読み書きすると…
シングル スレッド マルチ スレッド
読み
計算
書き
読み
計算
書き
読み
計算
読み
計算
読み
計算
書き
読み
計算
書き
……
……
switch
switch
書き込み終わる前にスレッド
が切り替わることがある
• 計算前の値を再度読んじゃう
だいぶ昔の計算結果で上書き
• 別スレッドで計算してた分が消える
lock
• 競合回避のためにlock (鍵)をかける
switch
switch
lock獲得
lock解放
lock獲得
獲得失敗
他のスレッドがlock獲得
しようとすると失敗する
その場でいったんスレッ
ド実行を停止
読み
計算
書き
lock
• 競合回避のためにlock (鍵)をかける
switch
lock獲得
lock解放
獲得~解放の間は、同時に2つ以上
のスレッドで実行されなくなる読み
計算
書き
lock獲得
lock解放
読み
計算
書き
lockの仕組み
• OSのスレッド スケジューラーに依頼
• lockがかかっていると、スケジューラーがスレッド
実行を止める
• 特権モードが必要
• 無駄にスレッド切り替えが増える
高コスト
switch
switch
lock獲得
lock解放
lock獲得
獲得失敗
読み
計算
書き
スレッド切り替えも高コスト
スレッド ローカル
var count = 0;
Parallel.For(0, num,
() => 0,
(i, state, localCount) => localCount + 1,
localCount => count += localCount
);
var count = 0;
Parallel.For(0, num, i =>
{
lock (sync)
++count;
});
×悪い例
○良い例
(さっきの「マシな例」)
lockしてスレッド間で同じ
データを読み書き
スレッドごとに別計算
最後に集計
おさらい
• lockは高コスト
• 特権モードが必要
• 無駄なスレッド切り替え発生
• スレッド間のデータ共有は高コスト
• (特に書き込み)
• キャッシュからメイン メモリへの書き戻し
• コアごとのキャッシュへの伝搬
• NUMA (非均一メモリ アクセス)
スレッドごとの独立性
• 性能を求めるなら
• スレッド間での同じ場所の読み書きをなくす
• Parallelクラスにはそのためのオーバーロードあり
var count = 0;
Parallel.For(0, num,
() => 0,
(i, state, localCount) => localCount + 1,
localCount => count += localCount
);
スレッドごとに別々に+1
最後にスレッドごとの結果を足す
気を付けるポイント
• 独立に計算できないと、並列化の利益少ない
• 順序依存とかがあると無理
交換法則、結合法則が大事
これが成り立たない演算は
並列化に向かない
さっきの++countループの例だと
この辺りに気を使って
アルゴリズム考える必要あり
和を2つに分解
(分解しても計算結果が一緒)
イベントの実装
[MethodImpl(MethodImplOptions.Synchronized)]
add { _disposed += value; }
lock (this)相当
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, va
disposed = Interlocked.CompareExchange(ref _disposed, hand
}
while (disposed != handler2);
}
lock-free※アルゴリズム
×C# 3.0までの実装(悪い例)
○C# 4.0以降の実装(良い例)
※ OS機能(特権モード必要)のlockを使わずに競合を避けること
おさらい
• lockは高コスト(再)
• 特権モードが必要
• 無駄なスレッド切り替え発生
• 旧実装はlock
[MethodImpl(MethodImplOptions.Synchronized)]
add { _disposed += value; }
add { lock(this) { _disposed += value; } }
※ lock(this)は性能面以外にも問題あり
旧コードはいろんな意味でレガシー
※
新実装
• lockなしで競合回避するためのアルゴリズム
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, valu
disposed = Interlocked.CompareExchange(ref _disposed, handle
}
while (disposed != handler2);
}
こいつがポイント
Interlocked
• CPUには「必ず原子的※に実行する保証付き」
な命令がいくつかある(interlocked命令)
• .NETの場合、Interlockedクラスを利用
※ atomic: 不可分な。途中で他のスレッドなどに割り込まれない保証
var count = 0;
Parallel.For(0, num, i =>
{
Interlocked.Increment(ref count);
});
例: 原子性保証付きのインクリメント
挙動的にはlock付きの++countと同じ
lockとinterlocked命令
• lockはOS機能
• 特権モード移行が必要
• スレッド切り替えの機会を増やす
• 任意の処理をlockできる
• Interlocked命令は単なるCPU命令
• 特権モード不要
• lockよりはだいぶ低コスト
• とはいえ、普通の命令と比べると1桁くらいは遅い
• 単純な処理しか用意されてない
• インクリメントとか
CAS※
• 特に重要なのがCAS命令
• .NET的にはInterlocked.CompareExchangeメソッド
※ compare and swapの略。比較しながら交換
Intel CPUの命令名称的には compare exchange
int CompareExchange(ref int loc, int value, int comp)
{
int ret = loc;
if (ret == comp)
loc = value;
return ret;
}
↓こういう意味のコードを原子性保証付きで実行する命令
比較しながらの値の交換
CAS
• 何が重要かというと
• 競合が起きたことを検知できる
• 「競合を避ける」よりははるかに低コスト
int CompareExchange(ref int loc, int value, int comp)
{
int ret = loc;
if (ret == comp)
loc = value;
return ret;
} 競合してたら元のlocとは違う値が返る
新実装がやってること
• 競合が見つかったらやりなおし
add
{
EventHandler handler2;
var disposed = _disposed;
do
{
handler2 = disposed;
var handler3 = (EventHandler)Delegate.Combine(handler2, valu
disposed = Interlocked.CompareExchange(ref _disposed, handle
}
while (disposed != handler2);
}
競合検知しながらの交換
競合してたら最初からやりなおし
いわゆる「楽観的排他制御」
eventの+=が競合することはほとんどないので、ほぼ1発
注意
• この手のlock-freeアルゴリズムは書くの大変
• 書いたはいいけど、テストが大変
• 普通はライブラリまかせ
• Taskクラス(が使ってるスレッド プール)
• System.Collections.Concurrent名前空間内のクラス
• eventの自動実装(C# 4.0以降)
内部的にlock-free実装なものの例:
まとめ
• スレッドは高コスト
• スレッド プール(Taskクラス)推奨
• I/O-boundな処理にスレッド不要
• ~Asyncメソッドの利用推奨
• 競合
• lockが必要
• できればlockも避ける
• そもそもスレッド間でデータ共有しないアルゴリズム
• lock-freeアルゴリズム(interlocked命令)
• 競合を避けるよりは、検知してやり直しの方が低コスト

Contenu connexe

Tendances

Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Etsuji Nakai
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpsonickun
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safeKumazaki Hiroki
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメYoji Kanno
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
実践イカパケット解析
実践イカパケット解析実践イカパケット解析
実践イカパケット解析Yuki Mizuno
 
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All ThingsUnityTechnologiesJapan002
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろうKota Mizushima
 
何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門masayoshi takahashi
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門Norishige Fukushima
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなKentaro Matsui
 
新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編infinite_loop
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!Genya Murakami
 
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロdigitalghost
 
オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫Yuta Imai
 
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンAkihiko Horiuchi
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 

Tendances (20)

Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
実践イカパケット解析
実践イカパケット解析実践イカパケット解析
実践イカパケット解析
 
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編
 
Docker Compose 徹底解説
Docker Compose 徹底解説Docker Compose 徹底解説
Docker Compose 徹底解説
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
 
オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫
 
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホン
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 

Similaire à 非同期処理の基礎

Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~CHY72
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3DKouji Hosoda
 
これからのコンピューティングとJava(Hacker Tackle)
これからのコンピューティングとJava(Hacker Tackle)これからのコンピューティングとJava(Hacker Tackle)
これからのコンピューティングとJava(Hacker Tackle)なおき きしだ
 
Boost.Flyweight
Boost.FlyweightBoost.Flyweight
Boost.Flyweightgintenlabo
 
Data-Intensive Text Processing with MapReduce ch4
Data-Intensive Text Processing with MapReduce ch4Data-Intensive Text Processing with MapReduce ch4
Data-Intensive Text Processing with MapReduce ch4Sho Shimauchi
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScriptbleis tift
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
how-calculate-cluster-coefficience
how-calculate-cluster-coefficiencehow-calculate-cluster-coefficience
how-calculate-cluster-coefficienceNorihiro Shimoda
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装MITSUNARI Shigeo
 
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キューYuto Takei
 
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワークisaac-otao
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタートShumpei Shiraishi
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナドKousuke Ruichi
 
ji-5. 繰り返し計算
ji-5. 繰り返し計算ji-5. 繰り返し計算
ji-5. 繰り返し計算kunihikokaneko1
 

Similaire à 非同期処理の基礎 (20)

Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3D
 
これからのコンピューティングとJava(Hacker Tackle)
これからのコンピューティングとJava(Hacker Tackle)これからのコンピューティングとJava(Hacker Tackle)
これからのコンピューティングとJava(Hacker Tackle)
 
Boost.Flyweight
Boost.FlyweightBoost.Flyweight
Boost.Flyweight
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
Data-Intensive Text Processing with MapReduce ch4
Data-Intensive Text Processing with MapReduce ch4Data-Intensive Text Processing with MapReduce ch4
Data-Intensive Text Processing with MapReduce ch4
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScript
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
how-calculate-cluster-coefficience
how-calculate-cluster-coefficiencehow-calculate-cluster-coefficience
how-calculate-cluster-coefficience
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー
 
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
詳解 ディープラーニング輪読&勉強会 3章後半ニューラルネットワーク
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
jenkinsで遊ぶ
jenkinsで遊ぶjenkinsで遊ぶ
jenkinsで遊ぶ
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
JavaScriptクイックスタート
JavaScriptクイックスタートJavaScriptクイックスタート
JavaScriptクイックスタート
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナド
 
Xtext 紹介
Xtext 紹介Xtext 紹介
Xtext 紹介
 
20120721_ishkawa
20120721_ishkawa20120721_ishkawa
20120721_ishkawa
 
ji-5. 繰り返し計算
ji-5. 繰り返し計算ji-5. 繰り返し計算
ji-5. 繰り返し計算
 

Plus de 信之 岩永

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話信之 岩永
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話信之 岩永
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理信之 岩永
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム信之 岩永
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型信之 岩永
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)信之 岩永
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ信之 岩永
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#信之 岩永
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1信之 岩永
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方信之 岩永
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6信之 岩永
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に信之 岩永
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform信之 岩永
 
Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3信之 岩永
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略信之 岩永
 

Plus de 信之 岩永 (20)

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話
 
C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理
 
C# 8.0 非同期ストリーム
C# 8.0 非同期ストリームC# 8.0 非同期ストリーム
C# 8.0 非同期ストリーム
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
 
C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)C# 8.0 Preview in Visual Studio 2019 (16.0)
C# 8.0 Preview in Visual Studio 2019 (16.0)
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1C# 7.2 with .NET Core 2.1
C# 7.2 with .NET Core 2.1
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に
 
Modern .NET
Modern .NETModern .NET
Modern .NET
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
Deep Dive C# 6.0
Deep Dive C# 6.0Deep Dive C# 6.0
Deep Dive C# 6.0
 
Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 

Dernier

[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdffurutsuka
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 

Dernier (9)

[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdf
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 

非同期処理の基礎