学习笔记6
- Unix/Linux系统多任务处理概述
- 多任务处理系统
- Unix/Linux系统的进程管理
- 实践过程
Unix/Linux系统多任务处理概述
1.进程管理:
- 进程是程序的执行实例。Unix和Linux支持多个进程同时运行,每个进程都有自己的独立地址空间和资源。这使得多个应用程序可以同时运行,互不干扰。
- 操作系统通过调度算法决定哪个进程在何时运行,以便实现公平的资源分配和响应时间。
2.多用户支持:
- Unix和Linux是多用户操作系统,可以同时支持多个用户登录并使用系统。
- 用户和组的权限管理机制确保不同用户之间的隔离和安全性。
3.进程间通信:
- Unix和Linux提供了各种进程间通信(IPC)机制,如管道、消息队列、共享内存和信号等,允许不同进程之间进行数据交换和协作。
4.文件系统:
- Unix和Linux使用层次化文件系统,允许用户组织和管理文件和目录。文件是操作系统中的核心资源之一。
- 权限和所有权机制确保文件的安全性和隐私。
5.调度器:
- 调度器是操作系统的一部分,用于决定哪个进程应该在CPU上运行。
- Unix和Linux使用优先级、时间片轮转等调度算法,以确保不同进程获得公平的CPU时间,同时允许优先级更高的进程优先运行。
6.多任务处理:
- 多任务处理是指系统能够同时运行多个任务,每个任务可以是一个应用程序或服务。
- Unix和Linux使用进程管理、线程管理和虚拟内存技术来实现多任务处理,使得系统可以同时执行多个任务而不会相互干扰。
7.虚拟内存:
- 虚拟内存是一种技术,允许将物理内存和磁盘空间结合使用,以扩展可用内存。
- Unix和Linux使用虚拟内存来管理内存资源,允许多个进程同时运行,而无需担心物理内存限制。
8.Shell和命令行界面:
- Unix和Linux提供了强大的命令行界面,用户可以通过Shell使用各种命令来执行任务、管理文件和配置系统。
9.网络支持:
- Unix和Linux系统内置了网络支持,允许计算机在网络上进行通信和共享资源。
- 这使得它们成为服务器操作系统的首选选择,支持各种网络服务。
10.可定制性:
- Unix和Linux是开源系统,用户可以根据自己的需求自定义和扩展系统。这使得它们非常适用于各种用途,从嵌入式系统到大型服务器。
多任务处理系统
1.多任务处理系统文件:
type.h
文件:定义了系统常数和表示进程的简单PROC结构体ts.s
文件:在32位GCC汇编代码中可实现进程上下文切换。queue.c
文件:可实现队列和链表操作函数。enqueue()
函数按优先级将PROC输入队列中。在优先级队列中,具有相同优先级的进程按先进先出(FIFO)的顺序排序。dequeue()
函数可返回从队列或链表中删除第一个元素。printlist()
函数可打印链表元素。t.c
文件:定义MT系统数据结构、系统初始化代码和进程管理函数。
2.多任务处理系统代码示例:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // 用于互斥操作的互斥锁
void task1() {
for (int i = 0; i < 5; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Task 1: Step " << i << std::endl;
}
}
void task2() {
for (int i = 0; i < 5; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Task 2: Step " << i << std::endl;
}
}
int main() {
std::thread thread1(task1);
std::thread thread2(task2);
thread1.join();
thread2.join();
return 0;
}
- 引入
头文件来使用多线程功能。 - 创建两个线程 thread1 和 thread2,它们执行不同的任务。
- 使用 std::mutex 来创建互斥锁 mtx,以确保线程之间的数据同步和互斥。
- 在任务函数中,使用 std::lock_guard 来锁定互斥锁,以确保每个线程一次只能有一个访问共享资源(std::cout)。
- std::this_thread::sleep_for 用于模拟任务的耗时操作。
Unix/Linux系统的进程管理
Unix/linux 中的进程
在Unix和Linux系统中,进程是操作系统的基本执行单位,用于执行各种任务和程序。
1.进程来源:
进程可以有多种来源,包括:
- 用户启动的进程:这是由用户通过命令行或图形用户界面启动的进程,用于运行应用程序。
- 系统启动的进程:这是在系统启动时由初始化进程(通常是INIT或systemd)启动的进程,用于初始化系统的各个组件。
- 守护进程:这是在后台运行的系统服务,通常由系统启动时或在需要时由初始化进程启动。
- 进程间通信:一个进程可以通过多种方式创建其他进程,例如使用fork系统调用。这些新进程可以执行不同的任务,与父进程共享一些资源。
2.INIT和守护进程:
- INIT:INIT是Unix系统中的初始化进程,通常是第一个进程,其PID为1。INIT负责系统的初始化和进程的管理,它通过启动和终止其他进程来维护系统的稳定性。在现代Linux系统中,systemd 已经取代了传统的INIT。
- 守护进程:守护进程是在后台运行的系统服务,通常没有与终端相关联。它们可以通过INIT或其他方式启动,负责提供各种系统服务,如网络服务(如sshd)、日志服务(如syslogd)等。守护进程通常在系统启动时自动启动,并持续运行,直到系统关闭。
3.登录进程:
- 登录进程负责用户登录和身份验证。在Unix和Linux系统中,最常见的登录进程是 getty 或 mingetty,它们等待终端用户登录并启动用户会话。
- 用户登录后,通常会启动一个shell进程,允许用户在系统上执行命令和操作。
4.sh进程:
- 当用户登录时,通常会启动一个shell进程,以便用户可以与系统进行交互。shell是一个命令解释器,它接受用户输入的命令并执行相应的操作。
- 常见的shell包括bash、sh、zsh、csh、fish等。用户可以根据自己的喜好选择不同的shell。
5.进程的执行模式:
- 前台进程:前台进程是当前与终端用户交互的进程,它接收用户的输入和输出到终端。用户可以在前台进程中执行命令并与之交互。
- 后台进程:后台进程是在后台执行的进程,不会与终端用户直接交互。用户可以在命令行中使用&符号来将一个进程置于后台运行。
- 守护进程:守护进程是在后台运行的系统服务,通常不与终端相关联。它们在系统启动时启动,持续运行以提供各种服务。
进程管理的系统调用
进程管理是操作系统的核心功能之一,用于创建、终止、调度和管理进程。为了实现这些功能,操作系统提供了一系列称为系统调用(system calls)的接口,供应用程序和用户空间的进程使用。
-
fork()
:fork 系统调用用于创建一个子进程,子进程是调用进程的精确复制,包括内存内容、代码、数据、文件描述符等。子进程与父进程同时运行,并在 fork 后继续执行。这个系统调用返回两次,一次在父进程中(返回子进程的PID),一次在子进程中(返回0)。 -
exec()
:exec 系统调用用于加载一个新的程序镜像到当前进程的地址空间,替代当前进程的代码和数据。这个系统调用通常用于启动新的程序。exec 有多个变种,如 execv、execl 等,用于不同的参数传递方式。 -
wait()
和waitpid()
:wait 和 waitpid 系统调用用于父进程等待子进程的终止,并收集子进程的终止状态。这些系统调用允许父进程获取子进程的退出状态码等信息。 -
exit()
:exit 系统调用用于终止当前进程的执行,并返回一个终止状态码。这个状态码可以被父进程的 wait 系统调用获取。 -
getpid()
和getppid()
:getpid 用于获取当前进程的PID(进程标识符),而 getppid 用于获取父进程的PID。 -
nice()
:nice 系统调用用于调整进程的调度优先级。较高的优先级值意味着进程会更少地被调度执行,而较低的值会使进程更频繁地执行。 -
kill()
:kill 系统调用用于向指定进程发送信号,可以用于终止进程、通知进程执行特定操作等。 -
setsid()
:setsid 系统调用用于创建一个新的会话,分离进程与控制终端的关联,通常用于守护进程的创建。 -
umask()
:umask 系统调用用于设置文件创建时的默认权限掩码,控制新文件的默认权限。 -
getrlimit()
和setrlimit()
:getrlimit 用于获取和 setrlimit 用于设置资源限制,如进程可以打开的文件数量、进程可以使用的内存等。