Linux的启动过程
Linux 的启动过程大致可以分为以下几个阶段:
1. BIOS/UEFI 加电自检
- 当计算机加电时,BIOS 或 UEFI 会首先执行一系列的硬件自检(POST,Power-On Self Test),检查系统是否正常运行。
- 接下来,BIOS/UEFI 会查找并加载存储设备上的引导加载程序(如硬盘、USB、光盘等),通常存储在主引导记录(MBR )或 GUID 分区表(GPT)中。
2. 引导加载程序(Bootloader)
- MBR 或 GPT 中的引导加载程序会被加载到内存。常见的引导加载程序包括 GRUB (Grand Unified Bootloader)或 LILO。
- 引导加载程序负责选择和加载 Linux 内核。它允许用户选择要启动的内核或操作系统(例如双系统选择)。
- 一旦用户选择了要启动的内核,GRUB 会将内核加载到内存中,并将控制权交给内核。
3. 加载 Linux 内核
- 内核被加载到内存后,它会解压并初始化自身。
- 内核首先会检测硬件设备,并加载相应的驱动程序,以便能够与硬件进行通信。
- 内核还会挂载根文件系统(通常存储在
/
),然后启动第一个用户空间进程------init
进程(PID 为 1)。
4. init
进程启动
init
是所有用户进程的祖先,它是用户空间中的第一个进程。- 在大多数现代 Linux 发行版中,
init
系统被替换为 systemd 或 Upstart,它们作为系统的初始化系统,负责启动所有其他进程和服务。 init/systemd
读取配置文件来决定哪些服务和守护进程应该启动。
5. 启动服务和守护进程
init/systemd
根据系统配置启动各种服务和守护进程(例如网络服务、日志系统、文件系统挂载、设备管理等)。- 这些服务在后台运行,为系统提供各种功能。
6. 用户登录界面
- 当所有的服务启动完成后,系统会进入用户登录界面。
- 如果系统配置为启动图形界面(X Window System 或 Wayland),图形登录管理器(例如 GDM、LightDM)会启动。
- 如果是纯终端模式,系统会启动终端登录提示符,用户可以在这里输入用户名和密码。
7. 用户会话
- 用户成功登录后,用户的会话环境被初始化,包括加载用户的环境变量和设置。
- 如果是图形化界面,窗口管理器或桌面环境(例如 GNOME、KDE)会被启动。
- 系统处于可用状态,用户可以开始使用系统运行应用程序。
总结
- BIOS/UEFI → 引导加载程序(GRUB) → Linux 内核 →
init/systemd
→ 启动服务 → 用户登录界面 → 用户会话。
死锁的原因
常见的死锁原因:
-
资源竞争
- 当多个线程或进程同时需要访问同一资源时,容易导致死锁。比如两个线程互相持有对方需要的资源,并且都不释放。
-
不当的锁定顺序
- 如果两个或多个线程获取锁的顺序不同,可能导致循环等待。例如,线程1获取了锁A,线程2获取了锁B,然后它们都试图获取对方的锁,就可能发生死锁。
-
嵌套锁
- 在持有一个锁的同时去获取另一个锁,容易造成资源的占有和等待,导致死锁。
-
资源不足
- 当系统资源不足或者无法分配足够的资源时,进程或线程可能被阻塞,进一步增加了死锁的可能性。
死锁的条件
1. 互斥条件(Mutual Exclusion)
- 资源只能被一个线程或进程独占使用。如果某个资源在被一个进程占用时,其他进程无法访问该资源。
2. 占有并等待(Hold and Wait)
- 进程已经获得了某些资源,同时又请求新的资源,但这些资源被其他进程占有,此时该进程保持对已经获得资源的占有,同时等待其他资源释放。
3. 不可剥夺(No Preemption)
- 已经分配给某个进程的资源不能被强制剥夺,必须由进程主动释放。当进程占有资源时,只有在它使用完资源并主动释放后,资源才能被其他进程使用。
4. 循环等待(Circular Wait)
- 存在一个进程等待环形链,即有一组进程相互等待资源释放。进程A等待进程B占有的资源,进程B等待进程C占有的资源,最后进程C又在等待进程A占有的资源。
线程卡住了可能会导致什么问题
1. 死锁(Deadlock)
如果一个线程在等待某些资源(如锁、信号量等),而这些资源正好被其他线程持有,且这些线程也在等待第一个线程释放的资源,就会导致死锁。死锁会导致多个线程互相等待,最终导致程序无法继续执行。
2. 资源阻塞(Resource Blocking)
一个线程如果因为卡住而不能继续工作,可能会占用系统资源,如内存、文件句柄、网络连接等。这些资源无法被其他线程或进程使用,可能会导致系统资源的枯竭,影响系统性能。
3. 响应时间增加(Increased Latency)
如果卡住的线程是负责处理用户请求或关键任务的线程,程序的响应时间将显著增加,甚至会导致系统看起来失去响应(假死)。
4. 线程饥饿(Thread Starvation)
一个卡住的线程可能会占用某些资源,导致其他需要这些资源的线程无法执行。这种情况可能导致线程饥饿,即其他线程长时间得不到执行的机会。
5. 数据不一致(Data Inconsistency)
如果线程卡住的位置涉及数据操作,可能导致数据状态不完整或不一致。特别是在共享资源或临界区操作时,卡住的线程可能持有锁,导致其他线程无法访问这些资源。
6. 程序崩溃或超时(Program Crash or Timeout)
如果线程卡住的时间过长,某些系统或应用可能会认为程序发生了异常,从而引发崩溃或触发超时机制,导致程序被强制终止。
7. 降低系统整体性能(Degraded System Performance)
卡住的线程可能会让系统的多线程优势无法充分发挥,影响系统的并行性能,导致其他任务的执行效率降低。
总结来说,线程卡住可能会导致死锁 、资源阻塞 、响应延迟 、数据不一致等问题,严重时会影响整个系统的稳定性和性能。