栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

哈工大操作系统实验6:地址映射和共享

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

哈工大操作系统实验6:地址映射和共享

前言

做这个实验大致上消耗了我三天时间,本来我是想在10月10号之前搞完的,但最终还是消耗到了现在,搞计算机行业或许真的要有一颗强大的心理。不然你真的回被各种各样的bug给搞麻来。从前天开始我就不停的在调试修改的过程中,而且由于自己不太明白如何在linux-0.11上利用gdb调试,以至于我只能不停的利用增加printf来试这样的方式来调试,其调试过程无疑是十分痛苦的。但好歹是走到了这一步,只剩下最后两个实验了,希望自己能够在10月15号之前搞完吧。

声明

这个实验严格意义上来说其实我并不算做出来了,因为实验要求的是要自己建立两个进程,分别为生产者进程和消费者进程,然后通过其进程之间共享内存来实现进程通信。然而,我也没想到原来我的前一个实验有问题,以至于如果分成两个进程的话会导致失败,在尝试了多种方法无果后,我只能选择利用在一个进程中利用fork()形成父子进程来做,也就是前一个实验那种情况。

实验

对于这个实验,其实相比于前两个实验来说,我觉得反而更加简单,把蓝桥实验楼上的实验册看一下,对地址映射有个较为全面的认识,然后自己再看看相关系统调用以及参考参考博客就差不多了,其中特别要注意逻辑地址,虚拟地址,线性地址,物理地址的概念。
就我自己理解来看,逻辑地址就是段偏移量,指的是对于段头的相对位置,虚拟地址就是段标识符:段偏移量,其中段标识符通过gdt表或者ldt表找到段描述符,而在段描述符中就存储着段基址,也就是线性地址的段基址,其中段基址加上偏移量就是线性地址。之后再通过线性地址映射到物理地址上,物理地址也就是数据存储的真实地址。
这个实验还有一个难点就是空闲虚拟地址的寻找,就此实验楼给了提示,在linux内核注释那本书上的13-6图上说明了程序虚拟内存情况。
如果自己能够在细心一点的话,就能够发现在pcb中就存储着这些信息。

代码

shm.c

#include
#include
typedef struct{
	int key;
	unsigned long addr;
}shm_t;
typedef int key_t;
shm_t shm[20];
int flag;
void __init__(){
	int i;
	for(i=0;i<20;i++){
		shm[i].key=0;
	}
}
int sys_shmget(key_t key,size_t size,int shmflag){
	if(!flag){
		__init__();
		flag=1;
	}
	if(size>4096){
		errno=EINVAL;
		return -1;
	}
	int i,shmid=-1;
	for(i=0;i<20;++i){
		if(shm[i].key==key)return i;
	}
	unsigned long addr_t=get_free_page();
	if(!addr_t){
		errno=ENOMEM;
		return -1;
	}
	for(i=0;i<20;++i){
		if(!shm[i].key){
			shm[i].key=key;
			shm[i].addr=addr_t;
			shmid=i;
			break;
		}
	}
	return shmid;
}
void* sys_shmat(int shmid,const void*shmaddr,int shmflag){
	if(shmid<0){
		errno=EINVAL;
		return -1;
	}
	unsigned long logic_addr=current->start_code+current->brk;
	int ret=put_page(shm[shmid].addr,logic_addr);
	if(!ret){
		//printk("errorn");
		errno=EINVAL;
		return -1;
	}
	return current->brk;
}

test_pc

//由于上个实验有问题,其信号量必须要全局,故只能如此
#define __LIBRARY__
#include
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ALLNUM 750
#define CUSTOMERNUM 5
#define BUFFERSIZE 10
typedef int key_t;
_syscall1(int,sem_wait,sem_t*,sem);
_syscall1(int,sem_post,sem_t*,sem);
_syscall1(int,sem_unlink,const char*,name);
_syscall2(sem_t*,sem_open,const char*,name,unsigned int,value);
_syscall3(int,shmget,key_t,key,size_t,size,int,shmflg);
_syscall3(void*,shmat,int,shmid,const void*,shmaddr,int,shmflg);
void Producer();
void Consumer();
int InPos=0;
int OutPos=0;
sem_t *empty,*full,*mutex;
int main(int argc, char **argv)
{
    pid_t pid;
    empty=sem_open("empty",10);
    full=sem_open("full",0);
    mutex=sem_open("mutex",1);
    pid=fork();
    if(pid!=0)
    {
        Producer();
    }
    else
    {
	Consumer();
    }
    wait(NULL);
    wait(NULL);
    sem_unlink("empty"); 
    sem_unlink("full");
    sem_unlink("mutex");
    return 0;
}

void Producer()
{
	int i=0;
	int shmid;
	void *shm=NULL;
	int *shared;
	int ans;
	shmid=shmget((key_t)1234,sizeof(int)*BUFFERSIZE,0);	
	if(shmid==-1){
		fprintf(stderr,"shmat failed 4n");
		exit(0);
	}
	shm=shmat(shmid,0,0);
	if(shm==(void*)-1){
		fprintf(stderr,"shmat failed 5n");
		exit(0);
	}
	shared=(int*)shm;
	for(i=0;i 
结果 


下一实验再见~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/320537.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号