Skip to content

Latest commit

 

History

History
157 lines (120 loc) · 7.33 KB

File metadata and controls

157 lines (120 loc) · 7.33 KB

Operating Systems Concepts

Definition

An Operating System (OS) is system software that manages computer hardware and software resources and provides common services for computer programs. It acts as an intermediary between the computer hardware and the user, making the computer usable and efficient.

Why are Operating Systems Important?

  • Resource Management: Manages CPU, memory, storage, and I/O devices efficiently.
  • Process Management: Handles the creation, scheduling, and termination of processes.
  • Memory Management: Allocates and deallocates memory to processes, preventing conflicts.
  • File System Management: Organizes and manages files and directories on storage devices.
  • User Interface: Provides a way for users to interact with the computer (GUI or CLI).
  • Security: Protects system resources and user data from unauthorized access.
  • Abstraction: Hides the complexities of hardware from application developers.

Key Operating Systems Concepts

  1. Processes:

    • Definition: An instance of a computer program that is being executed. It's an independent unit of execution with its own memory space, resources, and execution context.
    • Process States: New, Ready, Running, Waiting, Terminated.
    • Process Control Block (PCB): A data structure containing information about a process (e.g., PID, state, CPU registers, memory management info).
  2. Threads:

    • Definition: A lightweight unit of execution within a process. Threads within the same process share the same memory space and resources, but have their own program counter, stack, and registers.
    • Purpose: Enable concurrency within a single process, improving responsiveness and resource utilization.
    • Types: User-level threads (managed by application), Kernel-level threads (managed by OS).
  3. CPU Scheduling:

    • Definition: The process of determining which process or thread gets access to the CPU and for how long.
    • Algorithms: First-Come, First-Served (FCFS), Shortest Job Next (SJN), Priority Scheduling, Round Robin, Multilevel Queue.
    • Goal: Maximize CPU utilization, minimize response time, maximize throughput.
  4. Memory Management:

    • Definition: The process of managing the computer's primary memory (RAM).
    • Techniques:
      • Paging: Dividing memory into fixed-size blocks (pages) and processes into pages.
      • Segmentation: Dividing memory into variable-size logical blocks (segments).
      • Virtual Memory: Using disk space as an extension of RAM, allowing programs to run even if they are larger than physical memory.
      • Swapping: Moving processes between main memory and disk.
  5. File Systems:

    • Definition: The method and data structure that an operating system uses to control how data is stored and retrieved.
    • Concepts: Files, directories, paths, permissions, blocks, inodes.
    • Examples: NTFS (Windows), ext4 (Linux), APFS (macOS).
  6. Inter-Process Communication (IPC):

    • Definition: Mechanisms that allow independent processes to communicate and synchronize their actions.
    • Examples: Pipes, Message Queues, Shared Memory, Semaphores, Sockets.
  7. Deadlocks:

    • Definition: A situation where two or more processes are blocked indefinitely, waiting for each other to release resources.
    • Conditions for Deadlock: Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait.
    • Strategies: Prevention, Avoidance, Detection and Recovery.
  8. System Calls:

    • Definition: The programmatic way in which a computer program requests a service from the kernel of the operating system.
    • Examples: open(), read(), write(), fork(), exec().

Rust and Operating Systems Concepts

Rust is a systems programming language, meaning it's designed for building operating systems, embedded systems, and other low-level software. Its features directly address many OS concepts:

  • Memory Safety: Rust's ownership and borrowing system prevents common memory errors (e.g., use-after-free, buffer overflows) that are critical in OS development.
  • Concurrency: Rust's safe concurrency primitives (Mutex, Arc, Send, Sync) make it easier to write correct multi-threaded code, which is essential for OS kernels and user-space applications.
  • Low-Level Control: Rust provides fine-grained control over memory, pointers, and hardware, allowing direct interaction with OS features.
  • std::process: For interacting with processes.
  • std::thread: For creating and managing threads.
  • std::sync: For synchronization primitives (Mutex, RwLock, Channels).
  • std::fs: For file system operations.
  • std::net: For networking (sockets).
  • no_std: Allows writing code without the standard library, crucial for bare-metal OS development.

Rust Example: Process and Thread Interaction

1. Setup Cargo.toml:

[package]
name = "rust_os_concepts_example"
version = "0.1.0"
edition = "2021"

[dependencies]

2. Example Code (src/main.rs)

// src/main.rs
use std::process::{Command, Stdio};
use std::io::{self, Write, BufReader, BufRead};
use std::thread;
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("-- OS Concepts Example --");

    // --- Process Management: Spawning a child process ---
    println!("\n--- Spawning a Child Process ---");
    // Command to run: `echo "Hello from child process"`
    let mut child = Command::new("echo")
        .arg("Hello from child process")
        .stdout(Stdio::piped()) // Capture stdout
        .spawn()?;

    // Read output from the child process
    let stdout = child.stdout.take().ok_or("Child process did not have stdout")?;
    let reader = BufReader::new(stdout);

    for line in reader.lines() {
        println!("[Child Process Output]: {}", line?);
    }

    let status = child.wait()?; // Wait for the child process to exit
    println!("Child process exited with status: {}", status);


    // --- Thread Management: Spawning multiple threads ---
    println!("\n--- Spawning Multiple Threads ---");
    let mut handles = vec![];
    let shared_data = "Shared message"; // This is implicitly 'static or copied

    for i in 0..3 {
        let data_for_thread = shared_data.to_string(); // Clone for owned data
        let handle = thread::spawn(move || {
            println!("Thread {}: {} (Thread ID: {:?})", i, data_for_thread, thread::current().id());
            thread::sleep(Duration::from_millis(100));
        });
        handles.push(handle);
    }

    println!("Main thread continues its work.");

    for handle in handles {
        handle.join().unwrap(); // Wait for each thread to complete
    }
    println!("All spawned threads finished.");


    // --- File System Interaction ---
    println!("\n--- File System Interaction ---");
    let file_path = "my_os_file.txt";
    // Write to a file
    fs::write(file_path, "This is a test line.\nAnother line.")?;
    println!("Wrote to file: {}", file_path);

    // Read from a file
    let content = fs::read_to_string(file_path)?;
    println!("Read from file:\n{}", content);

    // Delete the file
    fs::remove_file(file_path)?;
    println!("Deleted file: {}", file_path);

    Ok(())
}