分页操作系统

操作系统将空间分割为固定长度的分片,称为页,每一页有固定的地址空间,分页将进程的地址空间分割成固定大小的单元,每个单元称为一页,也叫做页帧(页并不会完全用完,页内参与有一些碎片)。

操作系统利用分页为进程分配内存时,内存不必是连续的,只要为进程分配足够的页就可以。进程使用的页都是虚拟页,他被放置在物理页帧里。虚拟页0放在物理页帧3(前两个页帧为操作系统所用,用户级线程不能使用,操作系统正好用虚拟地址让前两个页帧对用户来说不可见,更为安全)。

但需要有一个数据结构记录每个虚拟也在物理内存中的位置。操作系统给每个进程保存一个数据结构,称为页表(之所以是页表,也是由于每个进程会分到多个页)页表为进程地址空间的每个虚拟页面提供地址转换。

虚拟地址转换为物理地址

虚拟地址被分为页地址和偏移地址,操作系统将存储页地址部分,操作系统将存储所有的页地址,在具体寻址时,将物理页地址偏移地址合并,得到真正的地址。即像CPU一样,也有一个地址的合并器。而进程的页表,则是一个哈希表,进程内部的每一个虚拟页会对以一个真实的物理页,这样造成一种错觉,

所以寻址过程是:

汇编语言的地址->转换为第X页偏移量为Y的地址(X页位虚拟页)->查询进程页表获取进程X页的物理地址Z->Z左移12位与Y相加得到真正的物理地址;整个过程中偏移量不变;

以movl <vidtual address>,%eax为例;mov 21 ,%eax这里的21是进程内的虚拟地址21,不是物理地址21.

页表存在哪里

对于32位的地址来说,每一页4kb,需要存储20位的页地址,即2^20次方的页地址,在内存中存储这些地址需要耗费巨大的内存空间,造成浪费。

页表在哪里:如果在内存里,这意味着每一次读写命令都要额外访问一次内存获取真实地址,这样会降低程序执行的速度。在获取真实的地址前,系统需要获取进程的页表项,这里需要一个页表基址寄存器,来记录每个继承页表的位置。

页表里有什么

页表由页表项组成,页表项里不仅有物理页帧,还包括对该页的描述,如该页是否允许读,写,执行,该页是否被分配,该页是否被访问过(注意到每一个描述都为是或否,因此正好使用一位来记录),这些描述被称为位:如有效位,保护位,存在位,参考位,脏位

从页表中获取:

movl 21,%eax;的过程为:

首先移除地址的偏移部分,留下页值,

假设页表是数组结构的,那么页就是数组的索引,通过页表基址寄存器+sizeof(PTE)获取该页在数组里的地址,使用AccessMemory(PTEAddr)获取该页表项(注意还不是地址),

根据页表项的位(如参考位,脏位,保护位等)判断此次操作是否合法,非法则抛出异常;

获取偏移地址(第一个地址去除页地址)之后与PTE.PFN<<PFN_SHIFT相加即得到PhysAddr,真实的物理地址,

调用函数AccessMemory(PhysAddr)完成取值;

线程

pthread_create是一个创建线程的函数,其参数如下:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

其中,thread是指向线程标识符的指针,attr是指向线程属性的指针,start_routine是线程运行函数的地址,arg是传递给线程运行函数的参数。

具体解释如下:

  1. thread:用于存储新线程的标识符,可以通过该标识符来操作该线程。
  2. attr:用于设置线程的属性,如果为NULL,则使用默认属性。
  3. start_routine:线程运行函数的地址,该函数必须返回void类型,并且只有一个void类型的参数。
  4. arg:传递给线程运行函数的参数。

  1. pthread_create是一个POSIX线程库函数,用于创建一个新的线程。它的原型如下:

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

    其中,thread是指向线程标识符的指针,attr是指向线程属性的指针,start_routine是指向线程函数的指针,arg是传递给线程函数的参数。

    在调用pthread_create函数时,它会创建一个新的线程,并将线程标识符存储在thread指向的内存中。线程属性可以为NULL,表示使用默认属性。线程函数start_routine必须是一个指向函数的指针,该函数接受一个void类型的参数,并返回一个void类型的值。arg参数是传递给线程函数的参数。

    在创建线程后,pthread_create函数会立即返回,并且新创建的线程会开始执行start_routine函数。

pthread_join是一个线程函数,用于等待指定的线程结束并回收其资源。当一个线程调用pthread_join函数时,它会一直阻塞,直到指定的线程结束为止。

在调用pthread_join函数时,需要传入两个参数:要等待的线程ID和一个指向线程返回值的指针。如果线程没有返回值,可以将第二个参数设置为NULL。

下面是pthread_join函数的函数原型:

 
 

int pthread_join(pthread_t thread, void **retval);

其中,thread参数是要等待的线程ID,retval参数是一个指向线程返回值的指针。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值