【Linux】线程的内核级理解&&详谈页表以及虚拟地址到物理地址之间的转化

简介: 【Linux】线程的内核级理解&&详谈页表以及虚拟地址到物理地址之间的转化

一、线程的概念

       对于进程来说,进程创建时间和空间成本较高,因为进程是承担分配系统资源的基本实体所以线程的出现就成为了必然。Linux线程与进程非常相似,Linux设计者在设计之初觉得如果再为线程设计数据结构和调度算法就会使整个系统变得十分复杂。地址空间和地址空间上的虚拟地址,本质就是一种资源,所以线程就在进程的基础上让不同的线程看到进程地址空间上的代码区中的不同代码,并让不同线程去执行不同的代码,这样同样也实现了线程的功能不同的线程在同一个进程地址空间中运行,共享相同的内存和其他资源。所以说线程是进程内部的一个执行分支,线程也是CPU调度的基本单位

       每个线程都有一个与之关联的task_struct结构体,该结构体包含了线程的状态信息、调度信息、资源使用情况等。CPU在执行调度的时候,根本就不用区分进程和线程,反正你们都有task_struct结构体,都是执行流。Linux中所有的可调度执行流都叫做轻量级进程

二、详谈页表以及虚拟地址到物理地址之间的转化

       磁盘中的数据块和内存中的数据块都是4kb大小。为了管理内存中每一块4kb大小的内存块,操作系统内核中会有描述该内存块的结构体,4GB的内存大小中就有1048576个内存块,再利用数组就能将整个内存管理起来,对于内存的管理就变成了对于数组的增删查改。所以,操作系统进行内存管理的基本单位就是4kb

       再谈页表,其实页表并不是只有一块数据结构,而是分为了页目录,页表。一个虚拟地址有32位,32位中的前10位用来表示处于页目录中的哪一个位置,页目录中最多可以存放 个页表的首地址,第11到20位用来表示处于页表的哪一个页表项,一个页表中最多也有 个页表项,一个页表项就对应内存中的一个4kb大小的数据块。最后12位用来确定数据块中的字节, 刚好就是4kb,正好可以确定是哪一个字节,所以后12位也叫做页内偏移

       如果再在页表项中加入访问权限审查,有没有被使用过等等标志位,就能对用户操作进行一些审查以及拦截,来保证内存访问的安全性。

       针对页表的这一种分页存储的模式,我们所写的函数编译完就是一块一块的虚拟地址,根据函数名就可以找到函数入口地址,各个函数就分配得到了不同的虚拟地址,也就是得到了不同的页表区域。同样的,我们只要给不同的线程分配不同的页表区域,就可以让不同的线程能够访问到页表的不同子集,进一步的,就可以让不同的线程访问到不同的代码,从而实现多线程技术。  

三、创建线程的小例子

thread:这是一个指向pthread_t类型的指针,用于获取新创建线程的线程ID。在调用pthread_create后,这个指针会被设置为新线程的ID。

attr:这是一个指向pthread_attr_t类型的指针,用于设置线程的属性,如栈大小、优先级等。如果这个参数为NULL,那么线程将使用默认的属性。通常情况下,如果你不需要设置特殊的线程属性,可以传递NULL。

 

start_routine:这是一个函数指针,指向线程开始执行时要调用的函数。这个函数通常被称为线程的“入口点”或“启动例程”。

arg:用于向线程的启动例程传递参数。你可以通过这个参数向线程传递任何类型的数据。如果你的启动例程不需要任何参数,可以传递NULL。

3.1、主函数

#include <iostream>
#include <unistd.h>
#include <pthread.h>
using namespace std;
 
void* newthread(void*)
{
    while (true)
    {
        cout << 22222222 << endl;
        sleep(1);
    }
    
}
 
int main()
{
    pthread_t pthread;
    pthread_create(&pthread, nullptr, newthread, nullptr);
    while(true)
    {
        cout << 11111111 << endl;
        sleep(1);
    }
    return 0;
}

3.2、makefile

myThread:testThread.cc
  g++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:
  rm -f myThread

可以看到两个线程就同时跑起来了:

相关文章
|
12月前
|
安全 网络协议 Linux
深入理解Linux内核模块:加载机制、参数传递与实战开发
本文深入解析了Linux内核模块的加载机制、参数传递方式及实战开发技巧。内容涵盖模块基础概念、加载与卸载流程、生命周期管理、参数配置方法,并通过“Hello World”模块和字符设备驱动实例,带领读者逐步掌握模块开发技能。同时,介绍了调试手段、常见问题排查、开发规范及高级特性,如内核线程、模块间通信与性能优化策略。适合希望深入理解Linux内核机制、提升系统编程能力的技术人员阅读与实践。
984 1
|
12月前
|
Ubuntu Linux
Ubuntu 23.04 用上 Linux 6.2 内核,预计下放到 22.04 LTS 版本
Linux 6.2 带来了多项内容更新,修复了 AMD 锐龙处理器设备在启用 fTPM 后的运行卡顿问题,还增强了文件系统。
|
12月前
|
Ubuntu Linux
Ubuntu 23.10 现在由Linux内核6.3提供支持
如果你想在你的个人电脑上测试一下Ubuntu 23.10的最新开发快照,你可以从官方下载服务器下载最新的每日构建ISO。然而,请记住,这是一个预发布版本,所以不要在生产机器上使用或安装它。
|
12月前
|
传感器 监控 Ubuntu
10 月发布,Ubuntu 23.10 已升级到 Linux Kernel 6.3 内核
硬件方面,Linux 6.3 引入了在 HID 中引入了原生的 Steam Deck 控制器接口,允许罗技 G923 Xbox 版赛车方向盘在 Linux 上运行;改善 8BitDo Pro 2 有线控制器的行为;并为一系列华硕 Ryzen 主板添加传感器监控。
|
12月前
|
Ubuntu Linux
Ubuntu24.04LTS默认采用Linux 6.8内核,实验性版本可通过PPA获得
IT之家提醒,当下的 Ubuntu 23.10 也是一个“短期支持版本”,该版本将在今年 7 月终止支持,而今年 4 月推出的 Ubuntu 24.04 LTS 长期支持版本将获得 5 年的更新支持。
|
12月前
|
监控 Ubuntu Linux
什么Linux,Linux内核及Linux操作系统
上面只是简单的介绍了一下Linux操作系统的几个核心组件,其实Linux的整体架构要复杂的多。单纯从Linux内核的角度,它要管理CPU、内存、网卡、硬盘和输入输出等设备,因此内核本身分为进程调度,内存管理,虚拟文件系统,网络接口等4个核心子系统。
1082 0
|
12月前
|
Web App开发 缓存 Rust
|
12月前
|
Ubuntu 安全 Linux
Ubuntu 发行版更新 Linux 内核,修复 17 个安全漏洞
本地攻击者可以利用上述漏洞,攻击 Ubuntu 22.10、Ubuntu 22.04、Ubuntu 20.04 LTS 发行版,导致拒绝服务(系统崩溃)或执行任意代码。
|
12月前
|
Ubuntu 机器人 物联网
Linux Ubuntu 22.04 LTS 测试版实时内核已可申请
请注意,在启用实时内核后您需要手动配置 grub 以恢复到原始内核。更多内容请参考: