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

情報工学科 3年生対象 専門科目
システムプログラミング
第1回 導入
第2回 Linux、分割コンパイル
情報工学科
篠埜 功
講義計画
OSの授業で学んだことをプログラミングを通し
て体験することを目的とする。
• スクリプト言語を用いたプログラミング
• システムコールを使ったプログラム作成
– ファイル操作
– プロセス
– シグナル
– プロセス間通信
• 簡易なweb serverを作成する
参考書
C言語によるUNIXシステムプログラミング入門,河野
清尊 著,オーム社 ¥2940(税込)
成績評価
• レポート課題(数回、4割程度)
• 期末試験(6割程度)
特別な理由が無い限り,追試などは行わない
連絡先
• 篠埜 功
居室: 豊洲校舎 14階 14K32
E-mail: [email protected]
講義用ページ: http://www.sic.shibaurait.ac.jp/~sasano/lecture/lecture.html
ここへスライドのファイルを置く。授業の日程もここ
に記述する。
Operating Systemとは
• コンピュータのハードウェアを人間にとって使
い易い形にして提供するプログラム
– ハードウェアの抽象化
– ハードウェア資源の管理
• 複数のプログラムが同時に要求を出した場合などに
対応
– ハードウェア資源を効率的に利用
• 複数のプログラムが同時並行で動いているとき
講義の前提
• オペレーティングシステムの講義内容の基
本的な部分を理解している
• C言語によるプログラミングに慣れている
• 関連科目
– オペレーティングシステム,プログラミング入
門1,2
本講義の概要
• OSについてLinuxを例として体験的に学習
• Linux上で、シェル、C言語によるシステムプ
ログラミング
Windows
ソースコードが非公開
Linux
ソースコードが公開されている
※情報工学科ではLinuxなどのUnix系OSに触れておく
のは必須。
学習目標
• オペレーティングシステムが提供するシステ
ムコールを用いるプログラムが書けるように
なる。
– ネットワーク、ファイル操作等
・プログラミングの幅(自由度)を広げることができる
・よりOSに近いレベルのプログラム開発を通して
OSの機能に対する理解度を深めることができる
ソフトウェア
システムコール
我々が書く通常の
プログラム
システムコール
カーネル(kernel)
カーネル:Linuxの核をなす部分。
ハードウェア、プロセスの管理を
する。
プログラムからシステムコールを呼び出すことにより、
Linux kernelが管理しているハードウェア(ハードディスク、
ネットワーク等)にアクセスしたり、他のプロセスと通信を
行ったりすることができる。通常は直接システムコールは
呼ばず、ライブラリ関数を呼び出す。(ライブラリ関数の中
でシステムコールが呼ばれる。)
ハードウェア
システムコールの例
User program
・・・・・・・・・・・
・・・・・・・・・・・
C言語ライブラリ関数
・・・・・・・・・・・
fscanf()
・・・・・・・・・・・
・・・・・・・・・・・
Data File
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
・・・・・・・・・・・
システムコール
read
シェル
• ユーザーとUNIXシステムの間のインタフェー
スとして機能するプログラム
– コマンド入力を受けつけ、解釈し、実行する。
csh, bash, tcsh等がある。
[課題] fingerコマンドで各自の使用しているシェルを確
認せよ。
$ finger sasano
のように、自分のユーザ名を引数として与えればよい。
シェルスクリプト
• シェルでは変数や繰り返し機能を用いることができ
る。
– 少し複雑な処理はC言語などでプログラムを書かなくても、
シェルの機能で簡単に行うことができる。
• ファイルに保存しておいてプログラムのように
実行することができる(シェルスクリプト)
シェルスクリプトの例
• あるディレクトリ中の、拡張子が.cのファイルすべてに
対して、.bakという拡張子をつけてバックアップをとる
。以下の内容のファイルをbackup.shという名前で作
成せよ。
#!/bin/sh
for file in *.c
do
echo $file
cp $file $file.bak
done
exit 0
課題
ディレクトリを一つ作成し、そのディレクトリ内に
.cを拡張子とするファイル(中身は何でもよい
)を3つ程度作り、作成したシェルスクリプトを
そのディレクトリで実行して確認せよ。
シェルスクリプトの利点
• 豊富なUNIXコマンド群を有効活用
• 例えば
– ディレクトリ内にある画像ファイル全てに対して,
プログラムによりある処理を施したい
• ディレクトリ内にある画像ファイルのみを抽出,繰り返
し演算
– 複数のファイルから,ある特定の文字列を含む
ファイルのみに対して何らかの処理をしたい
• 文字列検索による該当ファイル抽出,繰り返し演算
UNIXの誕生
• UNIX
– AT&T ベル研究所で1970年代に開発。
– 当時、MulticsというOSが複雑になり過ぎており、
単純なOSを作りたいということで作られた。
– 最初はアセンブリ言語で書かれていたが、当然
移植性が悪かった。移植性を高くするためにC言
語が開発され、CでUnixが書きなおされた。Cは
高級言語であり、かつ細かい処理も書け、システ
ムプログラミングに最適。
/bin/cshについて連絡
• 芝浦工大の環境において、/bin/cshは
/bin/tcshへのリンクになっていました。
ユーザインタフェース(1)
(参考書1.1節)
• GUI (Graphical User Interface)
• 画面でメニューやアイコンなどを見ながらマウスなどを
使って操作
• コマンド名を覚えなくてもアイコンで分かる。(たとえば、
Word, Internet Explorerの起動アイコンなど)
• 1973年 XeroxがAlto(アルト)を開発。初めてGUIを搭
載したコンピュータと言われている。
• Apple社のMacintosh、Microsoft社のWindows、
UNIX系OSのデスクトップ環境(X Window System上)
ユーザインタフェース(2)
• CLI (Command Line Interface)あるいはCUI
(Character User Interface)
– MS-DOSにおいては、 C:\> などのプロンプトに続
いてユーザがコマンドを入力
– UNIX系OSにおいては、シェルのプロンプトに続い
てユーザがコマンドを入力
– コマンド名を覚えなければならない。
– Windowsにおいては、MS-DOSのウィンドウ,
UNIX系OSのデスクトップ環境においては、端末エ
ミュレータのウィンドウを開くことによりCLIとなる。
GUIとCLIの比較(1)
• GUIは、マウスなどのポインティングデバイスを用いるので操
作に時間がかかる。
• CLIは、キーボード操作に慣れれば、操作が速い。
• (例)短い内容のテキストファイル(This is a test. など)を作成
する場合
– GUIでは、メインメニュー -> プログラム -> アプリケーション
-> テキストエディタ ---- データ入力 ---- ファイル -> 名前を
付けて保存 -> 名前の入力 -> 終了
– CLIの場合(今、試しに行う。)
$ cat > test.txt
This is a test.
<CTRL-Dを入力>
$
GUIとCLIの比較(2)
• シェルのパイプ機能を使って、複数のコマンド
をつなぎあわせて実行したりできる。
– (例) lsでファイルが多すぎるときに一画面文ずつ
表示
$ ls | less
• シェルのリダイレクト機能を使って入力元や
出力先を切り替える
– (例) カレントディレクトリのファイル名一覧をファイ
ルに書き出す
$ ls > filelist.txt
Linuxの誕生
• Linux
– Finland, ヘルシンキ大学の大学院生,Linus
Torvalds(ライナス・トーヴァルド氏)開発,1991
年
– MINIX(Andrew Tanenbaumが教育用に作成し
たUnix風OS)を実用化しようとしたが,了承が得
られず、Linusが自分で一から開発。インターネッ
ト上の多くのUNIXプログラマも協力し,発展
Linuxの特徴
• GPLというライセンスに基づいて、誰でも自由に
改変・再配布することが可能
• 他のOSに比べ、低い性能のコンピュータでも軽
快に動作
• ネットワーク機能やセキュリティーに優れ、安定
• 必要な機能だけを選んでOSを構築可能
• システムの構築・運用に必要なソフトウェア群(コ
マンド、インストーラ、ユーティリティ)とともに配布
。カーネルとこれらのソフトウェアをまとめた配布
パッケージをディストリビューション(distribution)と
いう
Linuxの特徴
• オープンソース
– ソースコードが公開されている
• GPL(GNU General Public License) --- copyleft
– 改変等は自由だが、改変後の配布時にソースコードを開
示しなければならない。
(参考) BSD license (Berkeley Software Distribution
License)はcopyleftではない。OSではFreeBSDなど、OS以
外ではPostgreSQLなどがBSD license。BSDをベースにした
ライセンス(BSD style lisence)ではApache、Python等。
Copyright と Copyleft
• 使用許諾契約書
– 通常の商用ソフトウェアは,ソフトウェアの使用に
関しての制限を設ける
• Copyleft
– フリーソフトウェアの使用に関して他者が制限を
設けることを禁じる
GPLに従って配布されているソフトウェアの例
gcc: Cコンパイラ
emacs: テキストディタ
C言語プログラミング
(参考書1.2節)
•
•
•
•
コンパイラとインタプリタ
Cコンパイラ(gcc)の使い方
Cコンパイラの処理の流れ(詳細)
静的リンクと動的リンク
コンパイラとインタプリタ
(参考書1.2.1節)
• コンパイラ(compiler)
– ある言語のプログラムを別の(低レベルの)言語のプログ
ラムに翻訳(translate)するプログラム
– 変換前のプログラム:ソース(原始)プログラム
– 変換後のプログラム:オブジェクト(目的)プログラム
• インタプリタ(interpreter)
– プログラムを直接、解釈実行するプログラム。ある言語の
インタープリタは、その言語を解釈実行する機械(である
ように振る舞うソフトウェア)。
コンパイラ
• プログラムを翻訳
• オブジェクトプログラムを生成
• コンパイラ
– C,Fortran,COBOLなどの高級言語を機械語に翻訳。ア
センブラを内部で呼び出す。
• アセンブラ
– アセンブリ言語を機械語に翻訳
オブジェクト
プログラム
ソースプログラム
C,Fotran,COBOL
アセンブリ言語
コンパイラ
アセンブラ
機械語
インタプリタ
• ソースプログラムを直接解釈して実行
• BASIC, Java Script, Perl, Ruby等。
ソースプログラム
BASIC,Perl,
Java Script, Ruby
インタプリタ
【解釈、実行】
コンパイラの構成
字句解析
構文解析
種々のフェーズ
オブジェクト
コード
コンパイル方式 vs インタプリタ方式
• 実行速度
– コンパイル方式 >> インタプリタ方式
• コンパイル方式:機械語に翻訳してから実行
• インタプリタ方式:直接解釈して実行
• コンパイル方式の方が実行速度は高速
• 実行の手間
– コンパイル方式 < インタプリタ方式
• コンパイル方式:プログラムを修正したらコンパイルし直
す必要がある。
• インタプリタ方式:プログラムを修正後、すぐ実行できる。
• 移植性
– (参考) Java Virtual Machine
インタプリタ方式の普及
1. CPU速度の向上
2. 移植性
•
•
コンパイル方式:機械語に変換(CPU、OSに依
存)
インタプリタ方式:同一のプログラムが全てのコ
ンピュータで動かせる
gcc(GNU C Compiler)の使い方
(参考書1.2.2節)
$ gcc オプション ファイル名
($ man gcc で使い方が表示される。)
Optionの例
(オプションは書かなくてもよい。)
-o name 実行ファイルをnameという名前で生成
-c
分割コンパイル(リンクはしない)
-lxxx
ライブラリファイルlibxxx.a
を検索。libc.aはdefaultでリンク。libm.aは算術演算
ライブラリで,-lmで指定。
$ gcc –print-file-name=libm.a でリンク時に使われる
libm.aの絶対パスが表示される。
filenameの拡張子(gccは拡張子によって処理を切り替える)
xxxx.c C言語ソースファイル
xxxx.s アセンブリ言語ソースファイル(-S オプション)
xxxx.o オブジェクトファイル(-c オプション)
他にも拡張子がいくつかある。
ライブラリ
• ライブラリ
– 再利用を目的として作成されたコンパイル済み関数群(例:
mathライブラリ libm.a 等)
• 置き場所
– /lib, /usr/lib など。
• gccはデフォルトでは標準Cライブラリ(libc.a)内の関数しか検索
しないため,追加したいライブラリがある場合には明示的に指
定する。
• 算術ライブラリ使用例:
gcc program.c -o program /usr/lib/libm.a
もしくは
gcc program.c -o program -lm
(リンカがlibm.aを検索する)
• -Lオプションでライブラリを探すディレクトリを追加指定できる。
ライブラリ
• 静的ライブラリ
– オブジェクトファイルの集合体(拡張子***.a)
• 例: /usr/lib/libc.a(標準Cライブラリ), /usr/lib/libm.a(算術
ライブラリ)
– ライブラリに格納されているプログラムで使う場合,
• 関数を宣言しているヘッダーファイルをインクルード
• プログラムコードとライブラリがリンカによって結合され,
1つの実行可能プログラムを生成
• 動的リンクライブラリ dynamic link library(あるいは共有ライブラ
リ shared library)がある。(次回説明)
– Linuxでは拡張子は.so、windowsでは.dll
– リンク時ではなく、プログラム実行時にメモリー上にロードされ
る。これにより、実行形式ファイルのサイズが小さくなる。
ヘッダーファイル
• ヘッダーファイル
– ライブラリ関数の型の宣言等が記述されているフ
ァイル。プリプロセス時に読み込む。
• Cの場合
– stdio.h (標準入出力ヘッダー)
– stdlib.h (標準ライブラリヘッダー)
– math.h (算術関数用ヘッダー)
– /usr/include, その下のサブディレクトリ
– -I(エルの小文字ではなく、アイの大文字)オプショ
ンでヘッダーファイル検索ディレクトリを追加指定
できる。
分割コンパイル
– C言語プログラムを一つのファイルに全部書くのではなく、
複数のファイルに分けて記述する。
– それぞれのCファイルは個別にコンパイルできる(分割コン
パイル)。.oファイルが生成される。
$ gcc –c test.c
などを実行すると、test.oというファイルが生成される。
– 再配置可能なコードが生成される。リンク時に解決。
– 一つのファイルを修正した場合、他のファイルのコンパイ
ルをやり直さなくてよいので、修正時のコンパイル時間が
短縮される。(ただし、リンクのやり直しは必要)
分割コンパイルによるコンパイル手順(例)
2つの整数値(int型)の足し算を行う関数addを定義したC言語フ
ァイルadd.cを作成し、分割コンパイル(add.oが生成される)
$ gcc -c add.c
2. ヘッダファイルの作成
– 関数addのプロトタイプ宣言 int add (int, int); を記述したファ
イルadd.hを作成
3. add関数を呼び出すmain関数を記述したC言語ファイルmain.c
を作成
– add.hをインクルード (#include “add.h” をファイルの先頭に
記述)
– gcc -c main.c
– リンクし、実行形式ファイルをmainというファイル名で作成
・ gcc -o main main.o add.o
1.
演習課題
• 2つのint型の足し算をする関数addを定義し
たCファイルadd.cを作成
• add関数のプロトタイプ宣言をadd.hに作成
• add (3,4) のような計算を行うmain関数を
main.cに記述
• さきほどの手順で、分割コンパイルをし、リン
クして実行形式ファイルmainを作成
• mainを実行
ライブラリの作成
• ライブラリ化したい関数を記述したソースファ
イルを作成。(add.c, mult.cなど)
• アーカイバ ar でアーカイブを作成
• 関数のプロトタイプ宣言を記述したヘッダーフ
ァイルを作成
ライブラリ(アーカイブ)作成手順(例)
• 複数のオブジェクトファイルをアーカイバ ar を用いて一つのファイ
ルにまとめる。(ar はオブジェクトファイルに限らず使えるが、普通
はライブラリ作成に用いる。)
– add.o, mult.o からアーカイブ libaddmult.a を作成
• ar crv libaddmult.a add.o mult.o
– addとmultのプロトタイプ宣言をaddmult.hに作成
– リンク
$ gcc -L. main.o -laddmult
あるいは $ gcc –L. main.c –laddmult でもよい。
あるいは $ gcc main.c libaddmult.a でもよい。
(実行ファイルをa.out以外にする場合は-oオプションで指定)
– (参考)ライブラリや実行可能プログラムに含まれる関数を調べ
るコマンド(nm)が使える。
演習課題
• 2つのint型の足し算をする関数addと掛け算をする
関数multをadd.c, mult.cに作成
• add.c, mult.cを分割コンパイル
• add.o, mult.oをarでまとめてlibaddmult.aを作成
• mult (add (3,4), 3)のような計算を行うmain関数を
main.cに記述
• リンクして実行