マルチスレッド処理 マルチプロセス処理について

Slides:



Advertisements
Similar presentations
システムプログラミング 第11回 シグナル 情報工学科 篠埜 功. 今回の内容 前回の補足( exit システムコールについ て) プロセス間通信 – シグナルの送信 --- 今回の内容 – パイプによる通信 – ソケットによる通信.
Advertisements

プロセスの生成とコマンドの実行 プロセスの生成とコマンドの実行 プロセス生成のシステムコール プロセス生成のシステムコール プロセス生成のプログラム例 プロセス生成のプログラム例 プログラム実行のシステムコール プログラム実行のシステムコール 子プロセスの終了を待つシステムコール 子プロセスの終了を待つシステムコール.
システムプログラミング 第10回 情報工学科 篠埜 功. 今回の内容 プロセス(続き) – execve システムコール 現在のプロセスを、引数に与えられたファイル(実行 形式ファイルあるいはシェルスクリプト等の実行可能 なファイル)を受け取り、現在のプログラムをそれで 置き換える(変身)。 fork.
連続系アルゴリズム演習 第2回 OpenMPによる課題.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
データ構造とアルゴリズム 第10回 mallocとfree
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
基礎プログラミング 第13回(2007年5月28日) 「関数」の補足説明 Report-Fの解説.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
第8回 プログラミングⅡ 第8回
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング システムプログラミング プロセス間通信(パイプ) 担当:青木義満
OSI7層の各層の1)名称 2)機能の簡単な説明 3)各階層に関連のあ る機器、規格などを5つ以上書いて下さい。
担当:青木義満、篠埜 功 情報工学科 3年生対象 専門科目 システムプログラミング 第8回、第9回 シグナル処理 担当:青木義満、篠埜 功
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
(B2) 親: minami, kazuki 多様な認証機器に対応する 認証システム (B2) 親: minami, kazuki.
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
Cプログラミング演習 中間まとめ2.
プログラミング論 ファイル入出力
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
EVENT プログラミングのスタイル 手続き型: ある決められた場所から開始され, その後は純粋に上から下に流れて行く方式. 実行したいことを, 順番に記述してゆく. 逐次処理形式コーディングの方法である。 今までの授業(情報処理2や3)で 行ってきたプログラミングの演習 bcc32やmake 手続き型.
C言語でスレッド (Pthread) 2007年1月11日 海谷 治彦.
Cプログラミング演習 第7回 メモリ内でのデータの配置.
プログラミング 4 記憶の割り付け.
メモリの準備 メモリには、その準備の方法で2種類ある。 静的変数: コンパイル時にすでにメモリのサイズがわかっているもの。 普通の変数宣言
アルゴリズムとデータ構造勉強会 第6回 スレッド木
プログラミング入門2 第11回 情報工学科 篠埜 功.
演習1の解答例の解説 2004年10月21日 海谷 治彦.
プログラミング入門2 第11回 情報工学科 篠埜 功.
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
プログラミング論 ファイル入出力
ネットワークプログラミング (5回目) 05A1302 円田 優輝.
Webプロキシ HTTP1.0 ヒント CS-B3 ネットワークプログラミング  &情報科学科実験I.
演習1の解答例の解説 2006年11月8日 海谷 治彦.
TCP/IPとプロセス間通信 2007年1月12日 海谷 治彦.
Talkプログラムのヒント 1 CS-B3 ネットワークプログラミング  &情報科学科実験I.
Cプログラミング演習 第10回 二分探索木.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
ネットワーク・プログラミング ソケットオプションとスレッド.
第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み
再帰的手続き.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング 3 2 次元配列.
IF文 START もしも宝くじが当たったら 就職活動する 就職活動しない YES END NO.
「マイグレーションを支援する分散集合オブジェクト」
ネットワーク・プログラミング デバイスドライバと環境変数.
第5回 プログラミングⅡ 第5回
高度プログラミング演習 (11).
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
ネットワーク・プログラミング 非同期I/Oとスレッド同期制御.
ネットワーク・プログラミング TCPサーバ.
モジュール分割.
ネットワーク・プログラミング 1対多のプロセス間通信.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
演算子のオーバーロード.
岡村耕二 UDP通信プログラム 課題と回答例 岡村耕二 情報ネットワーク.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
3.1 シューティングゲームの当たり判定 当たったら死亡.
ネットワーク・プログラミング マルチタスク.
ネットワーク・プログラミング プロセスとファイルシステム管理.
Webプロキシ HTTP1.1 ヒント CS-B3 ネットワークプログラミング  &情報科学科実験I.
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
分岐(If-Else, Else if, Switch) ループ(While, For, Do-while)
プログラミング 2 静的変数.
Presentation transcript:

マルチスレッド処理 マルチプロセス処理について CS-B3 ネットワークプログラミング  &情報科学科実験I

このスライドについて このスライドでは皆さんがプログラムを書いたり,関数を調べたりする過程で行き詰ると予想される部分について簡単に解説します このスライドの目的は自主学習のサポートであり,説明が簡略化されています.完全な理解には自主学習が必要なので注意してください.

目次 よくつまずくところ 解決方法の例 解決方法の例 その1 スレッドの動作 解決方法の例 その2 プロセスの動作 まとめ

よくつまずくところ 以下のようなプログラムのままになっていませんか? while(1) { fgets()でキー入力を取得; send()で入力文字を送信; recv()で相手からメッセージを受け取る; } キー入力しなければ 次に進めない 送っている最中は キー入力,受信ができない 受信待ちの間は キー入力,送信ができない

解決方法の例 send()もrecv()も独立して別々に処理してくれれば楽ですよね? 前処理 while(1) { fgets()でキー入力を取得; send()で入力文字を送信; } while(1) { recv()する; } 後処理

解決方法の例 その1 以下のような実装方法(スレッド)はどうですか? 前処理 send()用スレッド recv()用スレッド 後処理

スレッドの動作 1スレッド = 1関数 スレッドは指定された関数を1つ実行する (main()関数がもう一個あるような感覚) 必要な値は,構造体の中に保存してスレッド用関数に渡せる スレッド用関数内で,別の関数を利用することも可能

スレッドの作成について pthread.hのヘッダファイルをインクルード pthread_create関数でスレッドを作成  ・終了した子スレッドはpthread_join関数で解放  ・もしくはpthread_detach関数でデタッチしておく  ・親⇒子の強制終了はデッドロックの可能性がある  ・スレッド間通信には排他処理が必要となる                    などなど その他pthreadライブラリ関数について http://d.hatena.ne.jp/gikogeek/20070703や http://ja.wikipedia.org/wiki/POSIX%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89 などを参照

処理 int main() { /* send用スレッド作成 */ pthread_create(&SendthreadID, NULL, SendThreadMain, (void *)SendthreadArgs); /* recv用スレッド作成 */ pthread_create(&RecvthreadID, RecvThreadMain, (void *)RecvthreadArgs);  各種処理; return 0; } /* Sendスレッド用関数 */ void *SendThreadFunc(void *threadArgs) { 処理; /* Recvスレッド用関数 */ void *RecvThreadFunc(void *threadArgs) { 処理

新スレッド1 SendThreadMainの処理{ 処理; return 0; } 処理 処理 int main() { pthread_create(&SendthreadID, NULL, SendThreadMain, (void *)SendthreadArgs); /* recv用スレッド作成 */ pthread_create(&RecvthreadID, RecvThreadMain, (void *)RecvthreadArgs);  各種処理; return 0; } /* Sendスレッド用関数 */ void *SendThreadFunc(void *threadArgs) { 処理; /* Recvスレッド用関数 */ void *RecvThreadFunc(void *threadArgs) { SendThreadMainの処理{ 処理; return 0; } 新スレッド1 処理 処理

新スレッド1 SendThreadMainの処理{ 処理; return 0; } 処理 処理 int main() { pthread_create(&SendthreadID, NULL, SendThreadMain, (void *)SendthreadArgs); /* recv用スレッド作成 */ pthread_create(&RecvthreadID, RecvThreadMain, (void *)RecvthreadArgs);  各種処理; return 0; } /* Sendスレッド用関数 */ void *SendThreadFunc(void *threadArgs) { 処理; /* Recvスレッド用関数 */ void *RecvThreadFunc(void *threadArgs) { SendThreadMainの処理{ 処理; return 0; } 新スレッド1 処理 処理

新スレッド1 SendThreadMainの処理{ 処理; return 0; } 新スレッド2 RecvThreadMainの処理{ int main() { /* send用スレッド作成 */ pthread_create(&SendthreadID, NULL, SendThreadMain, (void *)SendthreadArgs); /* recv用スレッド作成 */ pthread_create(&RecvthreadID, RecvThreadMain, (void *)RecvthreadArgs);  各種処理; return 0; } /* Sendスレッド用関数 */ void *SendThreadFunc(void *threadArgs) { 処理; /* Recvスレッド用関数 */ void *RecvThreadFunc(void *threadArgs) { SendThreadMainの処理{ 処理; return 0; } 新スレッド1 処理 処理 RecvThreadMainの処理{ 処理; return 0; } 新スレッド2 処理

※具体的な実装方法は自主的に調べてみましょう int main() { /* send用スレッド作成 */ pthread_create(&SendthreadID, NULL, SendThreadMain, (void *)SendthreadArgs); /* recv用スレッド作成 */ pthread_create(&RecvthreadID, RecvThreadMain, (void *)RecvthreadArgs);  各種処理; return 0; } /* Sendスレッド用関数 */ void *SendThreadFunc(void *threadArgs) { 処理; /* Recvスレッド用関数 */ void *RecvThreadFunc(void *threadArgs) { SendThreadMainの処理{ 処理; return 0; } 新スレッド1 処理 処理 RecvThreadMainの処理{ 処理; return 0; } 新スレッド2 処理 ※具体的な実装方法は自主的に調べてみましょう

解決方法の例 その2 以下のような実装方法(プロセス)はどうですか? 前処理 send()用プロセス recv()用プロセス 後処理

プロセスの動作 プロセス = プログラムのクローン プロセスを作成すると,そのプログラムのコピーが作られる コピーされたプログラム(子プロセス)の実行開始位置は,先頭からではなく,元々のプログラム(親プロセス)と同じ続きの位置から = 親プロセス,子プロセスで以降の処理を分岐させる 変数の値も子プロセス作成時点のものがコピーされる (別領域)

プロセスの作成について fork関数でスレッドを作成 fork関数の返り値で自身が親か子を判定できる forkを使う際の幾つか注意点・・・  ・終了した子プロセスはwait(pid)関数で解放  ⇒これを怠るとゾンビプロセスが発生する  ・各プロセスの変数領域は異なっている  ⇒そのままではプロセス間で変数を共有できない  ⇒解決策:共有メモリ・パイプなど                     などなど

プロセスの動作 例えば… 親プロセス int main() { /* 子プロセスを作成 */ pid = fork(); if (親プロセス) { 親プロセスの処理; } else if (子プロセス) { 子プロセスの処理; return 0; 親プロセス 処理

プロセスの動作 例えば… 子プロセス 親プロセス int main() { int main() { /* 子プロセスを作成 */ pid = fork(); if (親プロセス) { 親プロセスの処理; } else if (子プロセス) { 子プロセスの処理; return 0; 子プロセス int main() { /* 子プロセスを作成 */ pid = fork(); if (親プロセス) { 親プロセスの処理; } else if (子プロセス) { 子プロセスの処理; return 0; 親プロセス 処理 処理

プロセスの動作 例えば… 子プロセス 親プロセス int main() { int main() { /* 子プロセスを作成 */ pid = fork(); if (親プロセス) { 親プロセスの処理; } else if (子プロセス) { 子プロセスの処理; return 0; 子プロセス int main() { /* 子プロセスを作成 */ pid = fork(); if (親プロセス) { 親プロセスの処理; } else if (子プロセス) { 子プロセスの処理; return 0; 親プロセス 処理 処理

プロセスの動作 例えば… 子プロセス 親プロセス ※具体的な実装方法の詳細は各自で調べてみましょう int main() { /* 子プロセスを作成 */ pid = fork(); if (親プロセス) { 親プロセスの処理; } else if (子プロセス) { 子プロセスの処理; return 0; 子プロセス int main() { /* 子プロセスを作成 */ pid = fork(); if (親プロセス) { 親プロセスの処理; } else if (子プロセス) { 子プロセスの処理; return 0; 親プロセス 処理 処理 ※具体的な実装方法の詳細は各自で調べてみましょう

まとめ マルチスレッド処理・マルチプロセス処理によって プログラムをsend()用とrecv()用に分けることで, 送受信を並行して行うことができる プロキシプログラムではselectとマルチスレッド処理・マルチプロセス処理の複数を使うことになるかもしれません このスライドのヒントはあくまでも実装方法の一例です (他の実装方法もあるかもしれません) 以上の内容をヒントにして,自主学習やプログラムの実装を進めてみてください