スレッド

Similar documents
スレッド

プロセス

プロセス

POSIXプログラミング Pthreads編

POSIXスレッド

並行システムの検証と実装

プロセス

Microsoft PowerPoint - kougi9.ppt

メモリ管理

( ) 3 1 ( ), ( ).. 1

04-process_thread_2.ppt

Microsoft PowerPoint ppt [互換モード]

POSIXスレッド

Insert your Title here

Taro-リストⅢ(公開版).jtd

NUMAの構成

第2回

pthreads #pthreads

Taro-リストⅠ(公開版).jtd

Microsoft PowerPoint ppt [互換モード]

memo

スレッド

Microsoft PowerPoint - CproNt02.ppt [互換モード]

memo

PowerPoint Template

r07.dvi

PowerPoint プレゼンテーション

ohp07.dvi

プログラミングI第10回

// このクラスの有効期間中の各呼び出しに使用される キャッシュされた Socket オブジェクト Socket socket = null; // 非同期処理が完了したことを通知するために信号を送るオブジェクト static ManualResetEvent clientdone = new Ma

オペレーティングシステム

Microsoft Word - Cプログラミング演習(12)

Microsoft Word - no12.doc

slide5.pptx

Microsoft PowerPoint - kougi11.ppt

program7app.ppt

Microsoft PowerPoint - 06.pptx

演算増幅器

一般的なスレッド : POSIX スレッドの説明 : 第 2 回 mutex というちょっとしたもの Daniel Robbins President/CEO Gentoo Technologies, Inc 年 8 月 01 日 POSIX スレッドは コードの応答性とパフォーマンスを

ただし 無作為にスレッドを複数実行すると 結果不正やデッドロックが起きる可能性がある 複数のスレッド ( マルチスレッド ) を安全に実行する ( スレッドセーフにする ) ためには 同期処理を用いるこ とが必要になる 同期処理は 予約語 synchronized で行うことができる ここでは sy

Prog1_10th

Microsoft PowerPoint ppt [互換モード]

Microsoft Word - 第5回 基本データ構造2(連結リスト).doc

Microsoft Word - no206.docx

I. Backus-Naur BNF : N N 0 N N N N N N 0, 1 BNF N N 0 11 (parse tree) 11 (1) (2) (3) (4) II. 0(0 101)* (

2006年10月5日(木)実施

IntelR Compilers Professional Editions

O(N) ( ) log 2 N

Microsoft Word - no15.docx

double float

オペレーティングシステム

Prog1_12th

Microsoft PowerPoint - kougi10.ppt

program.dvi

PowerPoint プレゼンテーション

ohp03.dvi

PowerPoint プレゼンテーション

Microsoft PowerPoint - kougi8.ppt

PowerPoint プレゼンテーション

ohp08.dvi

目次 1. DB 更新情報受信 SW 仕様書 構成および機能 全体の構成 DB 更新情報受信 SW の機能 ソフトウェアの設計仕様 DB 更新情報受信 SW の仕様 資料編... 5

file:///D|/C言語の擬似クラス.txt

memo

Microsoft PowerPoint - KHPCSS pptx

SuperH RISC engineファミリ用 C/C++コンパイラパッケージ V.7~V.9 ご使用上のお願い

スライド 1

I. Backus-Naur BNF S + S S * S S x S +, *, x BNF S (parse tree) : * x + x x S * S x + S S S x x (1) * x x * x (2) * + x x x (3) + x * x + x x (4) * *

Microsoft PowerPoint - 5_2-3IPC.pptx

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

PowerPoint プレゼンテーション

Microsoft Word - no205.docx

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

r08.dvi

memo

r03.dvi

PowerPoint Presentation

TopSE並行システム はじめに

II ( ) prog8-1.c s1542h017%./prog8-1 1 => 35 Hiroshi 2 => 23 Koji 3 => 67 Satoshi 4 => 87 Junko 5 => 64 Ichiro 6 => 89 Mari 7 => 73 D

新版明解C言語 実践編

memo

昨年度までの研究紹介 および 研究計画

Taro-スタック(公開版).jtd

Microsoft PowerPoint - OpenMP入門.pptx

slide4.pptx

Gfarm/MPI-IOの 概要と使い方

gengo1-12

Microsoft PowerPoint - OS04.pptx

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

:30 12:00 I. I VI II. III. IV. a d V. VI

( ) ( ) 30 ( ) 27 [1] p LIFO(last in first out, ) (push) (pup) 1

gengo1-12

プログラミング及び演習 第1回 講義概容・実行制御

Microsoft PowerPoint - OS06.pptx

02: 変数と標準入出力

マルチコア時代の並列プログラミング

:30 12:00 I. I VI II. III. IV. a d V. VI

Taro-ファイル処理(公開版).jtd

memo

Transcription:

POSIX スレッド (1) システムプログラミング 2009 年 10 月 19 日 建部修見

組込機器における並行処理 GUI における反応性向上 ダイナミックな Wait カーソル 各イベントを別制御で実行 Auto save 機能 サーバの反応性向上 各リクエストを別制御で実行 マルチコア マルチプロセッサでの並列実行

スレッドとは? プロセス内の * 独立した * プログラム実行 同一プロセス ID 注 :LinuxThreads は実装がプロセスなため異なる 論理メモリ空間を共有 ファイルディスクリプタなどプロセス資源を共有 一般にスレッド生成はプロセス生成より軽い

プロセス vs スレッド 生成 実行オーバヘッド スレッド小 プロセス大 メモリ 共有 別々 プロセス資源 共有 別々 データ共有 メモリのポインタ渡し ( コピーは不必要 ) パイプ ソケット ファイルなど 保護 他スレッドのメモリ 資源を破壊する可能性あり スレッドの実行制御が必要 他プロセスのメモリ 資源は保護される

その他のスレッドの便利な利用例 RPC( 遠隔手続き呼出 ) の遅延隠蔽 別スレッドで RPC を発行 非同期 IO と同等の処理 プログラム構造の単純化 表計算における入力処理 ( スレッド1) と合計値などの値更新 ( スレッド2) スレッド1は入力を処理 スレッド2は変更を待ち変更があれば更新

スレッドを利用すべきでない例 逐次的な処理自体の高速化が必要な場合 逐次的な数値計算 逐次的な IO 処理 ( ファイルの連続読込 連続書込 ) マルチスレッド処理はオーバヘッドとなる

並列性の制御 スレッド間でメモリ プロセス資源を共有しているため 破壊してしまう可能性がある 例 : 共有カウンタのインクリメント counter++ 1. counter の値をレジスタにロード 2. レジスタの値をインクリメント 3. レジスタの値を counter にストア スレッド 1 1. counter の値をレジスタにロード 2. レジスタの値をインクリメント 3. レジスタの値を counter にストア スレッド 2 1. counter の値をレジスタにロード 2. レジスタの値をインクリメント 3. レジスタの値を counter にストア

main(int argc, char *argv[]) { for (i = 1; i < argc; ++i) { if (i == 1) スライドショウのプログラム例 /* get the first picture */ buf = get_next_pic(argv[i]); else /* wait for the previous process */ pthread_join(tid, &buf); if (i < argc 1) /* get the next picture */ pthread_create(&tid, NULL, 表示している合間に次の get_next_pic, argv[i + 1]); 画像を読込 display_buf(buf); /* display the picture */ free(buf); if (getchar() == EOF) break; } }

スレッドの生成 終了 終了待ち #include <pthread.h> int pthread_create(pthread_t *threadp, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); void pthread_exit(void *status); void pthread_join(pthread_t thread, void **statusp);

Detached スレッド スレッドの終了状態が必要ないスレッド pthread_join の対象とできない pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&t, &attr, func, NULL); int pthread_detach(pthread_t thread);

同期 Mutex ロック pthread_mutex_t lock; int pthread_mutex_init( pthread_mutex_t *lock, const pthread_mutexattr_t *attr); pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; int pthread_mutex_destroy( pthread_mutex_t *lock);

Mutex ロック (2) int pthread_mutex_lock(pthread_mutex_t *mp); int pthread_mutex_unlock( pthread_mutex_t *mp); int pthread_mutex_trylock( pthread_mutex_t *mp); Mutex をロックしたスレッドがオーナとなる オーナ以外は mutex_unlock できない Trylock は lock できる場合は lock し できない場合は EBUSY を返す

データ競合 (data race) データ競合の定義 他のスレッドがアクセス可能な領域を 同時にあるスレッドが修正してしまう可能性のある場合 プログラムはデータ競合があるという Mutex ロックなどを利用して同期が必要 データ競合のないプログラムをデータ競合フリーという 共有変数を変更する場合 他スレッドがアクセスできないことを保証

共有カウンタのインクリメントの例 pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; int count; void increment_count() { pthread_mutex_lock(&count_mutex); // ensure atomic increment count++; pthread_mutex_unlock(&count_mutex); } int get_count() { int c; pthread_mutex_lock(&count_mutex); // guarantee memory is synchronized c = count; pthread_mutex_unlock(&count_mutex); return (c); }

条件変数 (condition variables) 条件が満たされるまで待つことに利用 基本操作 ( 条件が満たされたときに ) シグナルを送る ( 条件が満たされていなければ ) シグナルが送られるのを待つ 動作例 一つ以上のスレッドが条件変数で待つ 条件変数にシグナルが送られたら どれかのスレッドが実行を開始 誰も待っていない条件変数にシグナルが送られても無視される ( 状態を持たない )

条件変数の初期化 pthread_cond_t cond; int pthread_cond_init(pthread_cont_t *cond, const pthread_condattr_t *attr); pthread_cont_t cond = PTHREAD_COND_INITIALIZER; int pthread_cond_destroy( pthread_cond_t *cond);

シグナルの待機 送信 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast( pthread_cond_t *cond); cond_wait は mutex を unlock して cond にシグナルが送信されるまで待つ ( アトミックな操作 ) シグナルが送信されたら mutex を lock して実行を再開する

巡回バッファ #define QSIZE 10 /* キューの長さ */ typedef struct { pthread_mutex_t buf_lock; /* 構造体のロック */ int start; /* バッファの開始 */ int num_full; /* データの数 */ pthread_cont_t notfull; /* notfullの条件変数 */ pthread_cont_t notempty; /* notemptyの条件変数 */ void *data[qsize]; /* 巡回バッファ */ } circ_buf_t;

Puts new data on the queue void put_cb_data(circ_buf_t *cbp, void *data) { pthread_mutex_lock(&cbp >buf_lock); /* wait while the buffer is full */ while (cbp >num_full == QSIZE) } pthread_cond_wait(&cbp >notfull, &cbp >buf_lock); cbp >data[(cbp >start + cbp >num_full) % QSIZE] = data; cbp >num_full++; /* let a waiting reader know there s data */ pthread_cond_signal(&cbp >notempty); pthread_mutex_unlock(&cbp >buf_lock); 条件成立を while 文で待つ理由 巡回バッファを操作するときは mutex ロックする バッファが一杯の場合条件変数 notfull で待つ データを挿入, 条件式の更新 条件変数 notempty にシグナルを送信 cond_wait を抜けたからといって直後に Mutex ロックを獲得できるのは一スレッドのみ そのスレッドが条件式を更新する可能性があるため mutex ロックをアンロック

Gets the oldest data in circular buffer void *get cb_data(circ_buf_t *cbp) { } void *data; pthread_mutex_lock(&cbp >buf_lock); /* wait while there s nothing in the buffer */ while (cbp >num_full == 0) pthread_cond_wait(&cbp >notempty, &cbp >buf_lock); data = cbp >data[cbp >start]; cbp >start = (cbp >start + 1) % QSIZE; cbp >num_full ; /* let a waiting writer know there s room */ pthread_cond_signal(&cbp >notfull); pthread_mutex_unlock(&cbp >buf_lock); return (data); 巡回バッファを操作するときは mutex ロックする バッファが空の場合条件変数 notempty で待つ データを取出す, 条件式の更新 条件変数 notfull にシグナルを送信 mutex ロックをアンロック

論理条件 ( 式 ) と条件変数 論理条件式条件変数 FIFO キューが空 cbp >num_full == 0 cbp >notempty FIFO キューが一杯 cbp >num_full == QSIZE cbp >notfull それぞれの条件に対して別々の条件変数を使う必要はないが その場合 pthread_cond_wait で不必要に起こされてしまう可能性がある 条件変数の処理は比較的軽いため 無理に共有する必要はない mutex を unlock する前に signal を送るのは本質的ではない mutex を lock せずに条件となる式を更新すると lost wake up バグとなる ( 条件を評価したあと 条件が変更されシグナルが送信されると 次の pthread_cond_wait は決して起こされない )

タイムアウト付きで待つ int pthread_cond_timedwait( pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime); 条件変数にシグナルが送信されるか タイムアウトとなるまでブロックする タイムアウトの場合は ETIMEDOUT を返す