OSの主な役割
プロセッサー管理
- OSはCPUやメモリ、ディスク、ネットワークといったシステムリソースを効率的に割り当てます。これにより、複数のプログラムが同時に実行されても、システム全体のパフォーマンスが最大化されます
- 例えば、タスクスケジューリングという機能を通じて、複数のプロセスが公平かつ効率的にCPUを利用できるようにします。これには「ラウンドロビンスケジューリング」や「優先度スケジューリング」といった手法があります
プロセス管理
- プロセスとは、実行中のプログラムの単位です。OSはプロセスの生成、終了、実行スケジュール、リソースの割り当てを管理します
- マルチタスクでは、複数のプロセスが同時に実行されているように見えますが、実際にはOSが高速に切り替えることで実現しています
- また、スレッドという軽量プロセスの単位を利用することで、プログラム内の並行処理を効率的に行うことができます
ファイルシステム管理
- OSはデータをファイルとして保存し、これをディレクトリ構造で整理します。ファイルの作成、読み取り、更新、削除などの操作がユーザーやプログラムから簡単に行えるようにします
- さらに、複数のストレージデバイス(HDDやSSD)を統一的に扱うための抽象化を行い、データの整合性やアクセスの高速化を図ります
- NTFS(Windows)やext4(Linux)のようなファイルシステムがあります
デバイス管理
- OSはキーボードやマウス、プリンター、ディスプレイなどの入出力デバイスを制御します。これを実現するのがデバイスドライバというソフトウェアコンポーネントです
- デバイスドライバは特定のハードウェアとOSをつなぐ橋渡し役を担い、ユーザーがデバイスを意識することなく利用できるようにします
- 例えば、USBメモリを接続すると自動的に認識されるのは、デバイスドライバとOSが協力して動作しているためです
システムコール
システムコールは、プログラムがOSの機能を利用するためのインターフェースです。
一般のプログラムは直接ハードウェアを操作することができませんが、システムコールを通じて以下のような操作をOSに依頼できます。
-
ファイル操作
- ファイルの作成、読み書き、削除
-
プロセス管理
- プロセスの作成、終了、状態取得
-
デバイス操作
- デバイスへのデータ送受信
-
通信
- プロセス間通信やネットワーク通信
ユーザーモードとカーネルモード
OSはシステム全体を安全に管理するため、「ユーザーモード」と「カーネルモード」という2つの動作モードを用います。
ユーザーモード
- アプリケーションが動作するモードです
- 安全性を保つため、直接ハードウェアにアクセスすることはできません
- 例えばファイルを開きたい場合、アプリケーションが直接ディスクにアクセスするのではなく、システムコールを利用してOSに処理を依頼します
カーネルモード
- OSが動作する特権モードです
- ハードウェアリソース(CPU、メモリ、デバイスなど)への完全なアクセス権を持ちます
- システムコールを通じて、ユーザーモードの要求を受け取り、適切に処理します
モードの切り替え
ユーザーモードで動作中のアプリケーションがシステムコールを実行すると、以下の手順でカーネルモードに切り替わります。
- アプリケーションがシステムコールを発行
- モードがユーザーモードからカーネルモードに切り替わる(CPUが特定の割り込みをトリガー)
- カーネルが要求を処理
- 処理が完了すると、モードがカーネルモードからユーザーモードに戻る
- アプリケーションに結果が返される
システムコールのGoサンプルコード
package main
import (
"log"
"syscall"
)
func main() {
// "hello.txt"というファイルを作成してデータを書き込む
fd, err := syscall.Open("hello.txt", syscall.O_WRONLY|syscall.O_CREAT|syscall.O_TRUNC, 0644)
if err != nil {
log.Fatalf("ファイル作成エラー: %v", err)
}
defer syscall.Close(fd)
data := []byte("Hello, World!\n")
_, err = syscall.Write(fd, data)
if err != nil {
log.Fatalf("ファイル書き込みエラー: %v", err)
}
log.Println("処理完了")
}