linux课程设计

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Linux课程设计报告

专业班级:

学号:

姓名:

使用共享内存来完成进程间通信

一、相关原理介绍分析

1,共享内存的三种实现方式

(1)POSIX共享内存对象:shm_open创建一个名称为tmp的共享内存区对象后,在/dev/shm/下可以看到对应的文件(tmpfs的文件系统可以看成是直接对内存操作,速度非常快)。cat可以看到映射的内容。进程重启共享内存中数据不会丢失,内核自举或显示调用

shm_unlink或rm掉文件删除后丢失

(2)POSIX文件映射:通过映射一个普通文件(匿名文件或一个打开的命名文件)实现共享内存——mmap()。该方式的特点接口简单,较通用。可利用cat查看映射的文件,要注意考虑进程终止对通信的影响。该方式也是本实验使用的方式,下面将做具体表述。

(3)systemV共享内存:通过映射特殊存储块shm中的文件实现进程间的共享内存通信——主要有以下几个API:shmget()、shmat()、shmdt()及shmctl()。本方式无法看到文件实体。

进程重启共享内存中数据不会丢失,内核自举或显示调用shmdt或使用ipcrm删除后丢失。

2,POSIX文件映射共享内存简介

POSIX文件映射指mmap mmap()系统调用使得进程之间通过映射同一个普通文件实

现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一

样对文件进行访问,不必再调用read(),write()等操作。

3,POSIX文件映射共享内存实现方法

(1)文件与address_space结构的对应:一个具体的文件在打开后,内核会在内存中为之建立

一个struct inode结构,其中的i_mapping域指向一个address_space结构。这样,一个文件就对应一个address_space结构,一个address_space与一个偏移量能够确定一个page cache 或swap cache中的一个页面。因此,当要寻址某个数据时,很容易根据给定的文件及数据在文件内的偏移量而找到相应的页面。

(2)进程调用mmap()时,只是在进程空间内新增了一块相应大小的缓冲区,并设置了相应的

访问标识,但并没有建立进程空间到物理页面的映射。

4,主要函数介绍:

(1)void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )

①返回值为最后文件映射到进程空间的地址,进程可直接操作起始地址

②addr指定文件应被映射到进程空间的起始地址,一般被指定一个空指针,此时选

择起始地址的任务留给内核来完成。

③len是映射到调用进程地址空间的字节数,它从被映射文件开头offset个字节开始算起。

④prot 参数指定共享内存的访问权限。

PROT_READ(可读),

PROT_WRITE (可写),

PROT_EXEC (可执行),

PROT_NONE(不可访问)。

⑤flags由以下几个常值指定:

MAP_SHARED , (与private选择其一)

MAP_PRIV ATE ,

MAP_FIXED,(不推荐使用)

⑥fd为即将映射到进程空间的文件描述字,一般由open()返回,同时,fd可以指定为-1,

此时须指定flags参数中的MAP_ANON,表明进行的是匿名映射

⑦offset参数一般设为0,表示从文件头开始映射。

(2) int open( const char * pathname,int flags, mode_t mode);

①p athname 指向欲打开的文件路径字符串。

②f lags 所能使用的旗标:

O_RDWR 以可读写方式打开文件。

O_CREAT 若欲打开的文件不存在则自动建立该文件。

O_TRUNC 若文件存在并且以可写的方式打开时,此旗标会令文件长度清为0,而原来

存于该文件的资料也会消失。

③Mode有多种组合,只有在建立新文件时才会生效,此外真正建文件时的权限会受到

umask值所影响,因此该文件权限应该为(mode-umaks)。S_IRWXG 00777,代表具有可读可写可操作

二,设计实现

1,功能介绍

实现了共享内存机制。在一个终端上运行writer端,由于writer端得程序设置了八个缓冲区,因此可以依次输入,在另一个终端上运行reader端,在reader端可以读到数据并且屏幕输出。

实现了信号量同步机制。程序中应用了信号量,reader端和writer端不能同时对同一缓冲区进行操作。

2,程序结构框图

3,程序代码

(1)写者程序:w.c

#define NRBUF 8 //设置常数缓冲区的个数int empty[NRBUF];

int main()

{

/*数据结构的声明*/

int i=0,fd;

struct buffer_head *buf;

struct buffer_head bu[NRBUF];

char temp[20];

fd=open("arg",O_CREAT|O_RDWR|O_TRUNC,00777);//打开文件

truncate("arg",sizeof(bu)); //实际分配内存空间

buf=(struct

buffer_hea*)mmap(NULL,sizeof(bu),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

//非配缓冲区

close(fd);//关闭文件

/* 初始化信号量*/

for(i=0;i

{

empty[i] = CreateSem(1);//产生信号量 }

/* 初始化缓冲区*/

int k=0;

for(k=0;k

{

//(bu)->data =NULL;

(buf+k)->b_next=buf+k+1;

(buf+k)->sem = empty[k];

(buf+k)->lo = k+1;

}

(buf+NRBUF-1)->b_next = buf;

(buf+NRBUF-1)->sem = empty[NRBUF-1];

(buf+NRBUF-1)->lo = NRBUF;

i=0;

while(1)

{

/*进行PV操作 */

Psem(buf->sem);

printf(" writer 缓冲区%d :",buf->lo);

printf("请输入一个字符串");

gets(temp);

memcpy(buf->data,temp,20); //内存拷贝

buf=buf->b_next;

}

}

(2)读者程序:r.c

相关文档
最新文档