zhangbuda7788 blog

随写笔记_OS_05_20

一些关键字

进程:一个正在运行的程序的实例,是操作系统进程资源分配和调度的基本单位。每个进程都有自己的地址空间、内存、文件描述符、全局变量等资源。

特点:

组成:

linux 进程内核结构

代码段:存储可执行代码。


linux线程内核结构 在 Linux 中,线程被视为一种轻量级进程,它们共享同一个进程的某些资源,但每个线程都有自己的执行上下文。线程的内核结构也包含在 task_struct 中,但有一些共享和独立的部分:

进程地址空间:同一进程的线程共享相同的地址空间,包括代码段、数据段、堆和全局变量。

线程控制块(Thread Control Block, TCB):每个线程有自己的 TCB,存储线程的执行上下文,如寄存器状态、程序计数器和栈指针。


进程的生命周期

alt text

图片来源

参考02

进程通信

同一主机进程间通信

Unix 进程间通信

匿名管道 有名管道 信号

System V 进程间通信方式 、 POSIX 进程间通信方式

消息队列 共享内存 信号量

不同主机(网络)进程间通信

socket


管道

管道,本质是内核内存中维护的缓冲器,这个缓冲器的存储能力有限,不同的操作系统大小不一定相同。管道拥有文件的特质:读操作、写操作。匿名函数没有文件实体,有名函数有函数实体,但不存储数据。可以按照操作文件的方式对管道进程操作。

一个管道就是一个字节流,使用管道时不存在消息挥着消息便捷的概念,从管道读取数据的进程可以读取任意大小的数据块,而不管写入管道的数据块的大小。通过管道传递数据的顺序,从管道读取的顺序和这些数据从管道写入的数据是完全一样的。管道中数据的传递方式是单向的,一段用于写入,另一端用于读取,管道是半双工。 匿名管道只能在具有公共祖先的进程(父进程与子进程、两个兄弟进程,具有沁园关系)之间使用。

在 Linux 内核中,线程是通过轻量级进程(Lightweight Process, LWP)来实现的。每个线程有自己独立的线程控制块(Thread Control Block, TCB),但共享相同的进程控制块(Process Control Block, PCB)的一部分。Linux 内核通过 clone 系统调用创建线程,这个系统调用允许新线程共享调用者的地址空间和其他资源。
`**task_struct**

> 在 Linux 操作系统中,线程控制块(Thread Control Block, TCB)和进程控制块(Process Control Block, PCB)都被实现为一个统一的数据结构,即 task_struct。
> 这个结构体包含了操作系统管理进程和线程所需的所有信息。
> 实际上,在 Linux 中,没有专门的 TCB 和 PCB 结构,所有进程和线程共享相同的 task_struct 数据结构,只是使用该结构的方式不同。

`struct task_struct {
    // 进程状态
    volatile long state;

    // 链接到运行队列或等待队列的指针
    struct list_head tasks;
    struct list_head pushable_tasks;

    // 进程标识符
    pid_t pid;
    pid_t tgid;

    // 信号处理
    struct signal_struct *signal;
    struct sighand_struct *sighand;

    // 内存管理信息
    struct mm_struct *mm;
    struct mm_struct *active_mm;

    // 进程调度信息
    struct sched_entity se;
    struct sched_rt_entity rt;

    // 父进程、子进程
    struct task_struct __rcu *parent;
    struct list_head children;
    struct list_head sibling;

    // 线程信息
    struct thread_struct thread;

    // 文件描述符表
    struct files_struct *files;

    // 虚拟文件系统信息
    struct fs_struct *fs;

    // 用户和组信息
    uid_t uid, gid;
    struct group_info *group_info;

    // CPU相关信息
    struct cpumask cpus_allowed;
    int on_cpu;

    // 内核栈指针
    unsigned long stack;

    // 其他字段
    ...
};

轻量级线程vs携程

定义 轻量级线程是由操作系统内核管理的线程。它们可以并行执行,由内核进行调度和管理。

定义 协程是一种用户级别的并发机制,它们在用户空间中执行,通常由应用程序或运行时库进行调度。协程是非抢占式的,只有在协程显式挂起时才会切换到其他协程。

特性 轻量级线程 协程

管理者 操作系统内核 用户级库或运行时

调度方式 内核调度 用户级调度

并行执行 支持并行执行,多核处理器友好 通常不支持并行执行,多在单线程内

上下文切换开销 较大 非常小

阻塞 一个线程阻塞不影响其他线程 一个协程阻塞会导致整个线程阻塞

资源共享 共享进程资源 共享线程资源

使用场景 CPU 密集型和 I/O 密集型任务 I/O 密集型任务和异步编程


进程结束,自己的地址空间当中的用户数据会被释放,但是内核区的PCB无法自己释放,需要父进程释放,如果进程终止,父进程没有回收(wait、waitpid),子进程残留的资源(PCB)存放与内核中,这个进程就变成了僵尸进程。僵尸进程不能被kill -9 杀死,然后内核的PCB信息一直占用,进程号也一直占用,但是系统的进程号是有限的,当产生大量僵尸进程,可能会导致没有可用的进程号而导致不能产生新的进程。

父进程运行结束,但是子进程还在运行(未结束)。当出现孤儿进程时,内核会把孤儿进程的父进程设置为init,而init进程会循环地wait()它已经退出的子进程。孤儿进程没有什么危害。




一些补充 from gpt

轻量级线程

资源共享: LWP 共享同一个进程的地址空间、文件描述符、信号处理等资源,这使得它们之间的通信和切换比进程更快。

在不同的操作系统中,LWP 的实现方式有所不同。例如:

Linux: 在 Linux 中,轻量级进程通常通过 clone 系统调用来创建。clone 允许新线程共享其父线程的资源,例如地址空间和文件描述符。 Linux 中的线程库(如 POSIX 线程库 pthread)实际上使用的是轻量级进程。 Solaris: 在 Solaris 中,LWP 是一种特殊的调度实体,结合了用户级线程和内核级线程的优点。

相似性: 两者都表示可以被独立调度的执行单元。 共享同一进程的地址空间和资源。

优点

快速切换: 由于共享同一地址空间,LWP 之间的上下文切换比进程切换更快。

资源竞争: 由于 LWP 共享同一进程的资源,可能导致竞争资源,如锁争用问题。


我发现,得不断思考、重复总结,才能把一些知识点吃透、吃烂


未完待续…

#操作系统 #随写