PowerPoint プレゼンテーション

システムプログラミング演習
•
本資料は演習時間内の説明用として利用したものを,学生の希望にのっとり,掲載す
るもので,説明の攻勢などはかなりばらばらです.適宜,本来のプリント資料を参考し
てください.
田浦
情報源
• UNIX : manページ
– man recv
– man 2 recv
– man 3 recv
• Windows : MSDNライブラリ
インターネットの復習
• IPアドレス
– 133.11.23.10 etc.
• IP (Internet Protocol)
– IPアドレスを指定すると(世界中どこへでも)パケットを
がんばって届けてくれる(実はウソ)
– 失敗あり
• TCP (transfer control protocol)
– IPの上の“reliable”なレイヤ
– ポート番号による複数の入り口・出口管理
– 数え切れないアプリがこれを利用している
IPアドレスを調べてみよう
• Win ipconfig
• Unix ifconfig –a
• 接続時に自動的に重複なく割り当てられて
いることがほとんど(DHCP)
さっきのはウソ
• 一部のアドレスは「ローカルアドレス」
– 10.0.0.0 – 10.255.255.255
– 172.16.0.0 – 172.31.255.255
– 192.168.0.0 – 192.168.255.255
• LANの外からはつなげない
– でもLANの定義は微妙…
ソケット
• プロセス間通信(含むインターネット通信)
のためのAPI
• 本演習ではソケットをTCPを用いたイン
ターネット通信のために使う
基本概念
• クライアント(=電話をかける人)
s = socket(…);
connect(つなぎたいIPアドレスとポート); /* 電話
かける */
send/recv(s, …);
• サーバ(=電話を受ける人)
s = socket(…);
sにIPアドレスとポートを割り当て(電話番号登録);
new_s = accept(s); /* 待ち受け */
send/recv(new_s, …);
ソケット練習課題
• 送られてきた文字列を表示するだけの
サーバ
– ブラウザがどんな文字列を送ってきているの
かを調べるのに役に立つ
HTTP/HTML
• ブラウザとWebサーバのやり取り(のほんの一部)
– HTTP (Hypter Text Transfer Protocol)
– HTML (Hyper Text Markup Language)
• テキスト・参考書を読むのもよいが,
–
–
–
–
ブラウザは既にHTTPのリクエストをしゃべる
サーバは既にHTTPのリプライをしゃべる
先の課題でブラウザのメッセージを表示できる
telnetコマンドでサーバの返事を表示できる
先週の復習
サーバ
クライアント
connect
accept
GET <パス> HTTP/1.0
…
<空行>
send
recv
send
HTTP/1.1 200 OK
…
<空行>
<ページの内容>
recv
入力パス名と状態遷移
/
/new_n/
remember
78478931
セッション(ゲーム)ID
new game
6 digits
8 digits
…
/xxx_S/
/xxx_?/
(不正解)
next
1 2 … END
wrong!
/xxx_E/
(正解)
congrat!
/xxx_n/
(正解)
複数ゲームの同時進行が可能
な構成
/
/new_n/
/new_n/
new game
6 digits
8 digits
…
/new_n/
/new_n/
スレッドの概念
• スレッド: プログラムの文面を順に実行する「主
体」
• main() {
…
}
で … が実行されるのは,OSがmainを実行する
スレッドを生成して実行しているから
• プログラム中でスレッドを生成するAPIが存在す
る
スレッドAPI
• UNIX: POSIXスレッド(Pthreads)
• Windows: Win32スレッド
• 概念はほとんど同じ(見た目はソケットほど
似てはいないが…)
– 生成
– 同期(タイミングの制御)
• 以下,Pthreadsに準じて説明
生成
• pthread_create(…, f, x, …);
– f (x)を実行する「スレッドを生成」
• つまり,
pthread_create(…, f, x, …);
<…>
で,f (x)と<…>が並行に実行される
• f (x)と<…>はメモリを共有する
“並行に”実行されるとは?
• たくさんCPUがあれば本当に「同時に」実
行される
• 一般には,「あるだけのCPU」を「存在する
だけのスレッド」がかわりばんこに使う(OS
の制御)
• プログラムは「かわりばんこ」を意識しなく
てよい
プログラムの書かれ方
実際
CPU
スレッド利用上
の大注意
• 次の結果は?
initially:
x = 1;
スレッド1:
f ()
{
x = x * 10;
}
スレッド2:
g ()
{
x = x * 5;
}
同期の概念
• スレッドの「実行タイミング」の制御
– 排他制御: 「これ」と「あれ」を同時に実行して
はいけない(順番はどうでもよい)
– 生産者消費者同期: 「これ」がおわってから「あ
れ」を実行すべし
• 両者とも頻繁に用いられ,本課題でも使う
排他制御
pthread_mutex_t m;
pthread_mutex_init(&m);
スレッドA:
…
pthread_mutex_lock(&m);
スレッドB:
…
pthread_mutex_lock(&m);
pthread_mutex_unlock(&m);
…
pthread_mutex_unlock(&m);
…
生産者消費者同期
• 疲れるのでまた来週(テキストを読んでお
いてください)
本課題でのスレッドの利用
• 全てのリクエスト(acceptからのreturn)に「そ
のリクエスト処理」スレッドを生成
– / : これまでどおり
– /new_yyy/ : (新しいセッション)だったら,その
スレッドは,「そのセッション専門スレッド」にな
り,以降そのセッションへのメッセージを待つ
– /xxx_yyy/ : セッションID xxx に対応するス
レッドに yyy を渡す
mainスレッド
accept
/
/new_?/
これまで通り
セッションスレッド
wait_for_msg
/xxx_yyy/
セッションスレッド
xxxにメッセージ
yyyをとどける
正しい受け渡しの
ための同期!
本日のメニュー
•
•
•
•
生産者消費者同期
その他課題について
おまけ(1) 本物のwebサーバとの違い
おまけ(2) VMWare & Linuxオペーレーショ
ン
生産者消費者同期とは
• スレッドSの操作Aがお
わるまで,スレッドTの
操作Bを待たせたい
• 典型的な状況
S
A
T
result = 10;
– A : データの生産者
– B : データの消費者
• but, 上に限らず頻出す
る状況
… = result;
B
本課題の生産者消費者同期
メインスレッド
G: セッション(1スレッド/ゲーム)
create
R: リクエスト処理
1スレッド/リクエスト
put_data
get_data
• 注: 実は2つの同期の複合
– GはRが書く前に読んではいけない
– RはGが(一つ前のデータを)読む前に(次のデータを)
書いてはいけない
– 「有限バッファ」問題
条件変数(condition variable)
• 一般的に,「ある条件が成立するまで待
つ」を実現するprimitive
–
–
–
–
–
例 (いくらでも…)
x + y > 0 になるまで待つ
Q (queueオブジェクト)が空でなくなるまで待つ
f (x, y, z)が成立するまで待つ
要するに何にでも使える強力primitive
基本フォーム
• C(x, y, z)が成立するまで待ちたい時:
• pthread_mutex_lock(m);
while (!C(x, y, z)) {
mを解放しブロックする;
起きたらまたmをlock;
}
x, y, zなどをいじる
必要なら,他の待ってる人たちを起こす
pthread_mutex_unlock(m);
条件変数API
• pthread_cond_t c; pthread_mutex_t m;
• pthread_cond_init(&c);
• pthread_cond_wait(&c, &m);
– mをunlockし,cの上でブロックする.起こされ
たらまたmをlockする
• pthread_cond_broadcast(&c);
– cでブロックしている人全員をたたき起こす
有限バッファ with 条件変数
• 容量1の有限バッファ
• typedef struct {
int data;
int full;
mutex_t m;
cond_t c
} bb;
有限バッファ with 条件変数 (2)
• bb_get(bb * b) {
lock(&b->m);
while(!b->full) wait(&b->c);
t = b->data;
b->full = 0;
broadcast(&b->c);
return t;
}
有限バッファ with 条件変数 (3)
• bb_put(bb * b, int x) {
lock(&b->m);
while(b->full) wait(&b->c);
b->data = x;
b->full = 1;
broadcast(&b->c);
}
関連primitive: セマフォ
• mutexの一般化
• Windows, Solaris (not in Linux)
– sema_t s;
– sema_init(&s, c, …);
• s.x = c;
– sema_wait(&s);
• s.x > 0になるまでブロック,s.x--;
– sema_post(s);
• s.x++
補足(1) セッションID
• セッションIDの簡単な生成法=スレッドのス
タック上の変数のアドレス
– do_session() {
char dummy;
long session_id = (long)&dummy;
…
}
補足(2) 有限バッファメモリ管理
• typedef struct { … } session_table_entry;
• session_table_entry
session_table[MAX_SESSIONS];
• 操作:
–
–
–
–
新しいsessionの登録
与えられたsession IDのentry検索
いたるところに同期が必要
本課題ではむなしいが,10000 req/secのサーバを作っ
ている気分で
おまけ(1) 巷のwebサーバとの
違い
• 本物のwebサーバは
– 状態をメモリに残さない.データベースと連携.
セッションIDをcookieとしてブラウザに送り返
す
– 基本サービス以外は外部プログラム(CGI)を
起動する(拡張性)
– スレッドプール(同時処理に上限)
– スレッドの変わりにプロセスを使うこともある
おまけ(2): VMWare/Linux
オペレーション
• Linux in VMWareをインターネットにつなげる
–
–
–
–
VMWareのネットワーク構成
IP接続
WWWブラウザ
メール
• Linux in VMWare  ホストWindowsとの通信
– ホスト -> ゲストの接続
– ファイルコピー
– ファイル共有
VMWareのネットワーク構成
 (外向き接続)
 (内向き接続)
Bridged
インターネット
LAN (ローカルアドレス)
またはインターネット (グ
ローバルアドレス)
NAT
インターネット
ホスト
Host-Only
ホスト
ホスト
• 残念なこと 無線LANではBridgedでは使え
ない
診断手順
• /sbin/ifconfig –a
• ping
• TCP接続
– ブラウザ->webサーバ
– telnet->何かのサーバ(web, メール, etc.)
– 本演習で作ったプログラム!
ダメなとき
• /sbin/ifconfig –aでIPアドレスが変(0.0.0.0と
かゴミっぽい)
– /sbin/ifdown –a
– /sbin/ifup –a
• 直らなければ?
– NAT/Host-Onlyでやってみる
– 複数の同時接続を許すISPか? 許さなければ
Bridgedは無理
ダメなとき
• pingが通らない
– 近場(=ホストOS)に通す
• ホストOS (Windows)のアドレスはipconfigでチェッ
ク
• Bridged, NAT, Host-Onlyで見るべき値が違う
• 近場に通らなければLinuxの問題か?
• 近場に通るがインターネット(e.g., yahoo)に通らな
い
– Host-Onlyじゃない?
– ファイアウォールなど?
pingが通るけどWWWが動かな
い
• あまりない…
pingが通るがメールが動かない
• まずメールの設定をせよ
• emacs + mew
– 設定方法は後日HPにのせます
設定したがなぜか動かない
• 色々な理由がある
– SPAMとの戦い
• メールの仕組みを多少知っておいたほうが
良い
メールの仕組み
メーラ
(mew, outlook)
送信(認証なし)
ポート25
SMTPサーバ
受信 (認証あり)
POP/IMAPサーバ
ポート110 (POP)
メールが送れないありがちな理
由
• SMTPサーバ設定ミス
– telnet <サーバ名> 25でつながるか?
• 受け取りを拒否される
– ありがち: SMTPサーバが,LAN外からの送信
を拒否している
• × 大学 -> ISPのメールサーバ
• × ISP -> 大学のメールサーバ
メールが受け取れないありがち
な理由
• POP/IMAPサーバ設定ミス
– telnet <サーバ名> 110 (POP)
– telnet <サーバ名> 143 (IMAP)
– でつながるか
• LAN外からの危ない認証法拒否
– ×大学 <- ISP POPサーバ
– × ISP <- 大学 POPサーバ