操作系统实验进程通信

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

进程通信(实验二)

【实验目的】:掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。

【实验原理】:邮箱机制类似于日常使用的信箱。对于用户而言使用起来比较方便,用户只需使用send()向对方邮箱发邮件receive()从自己

邮箱取邮件,send()和receive()的内部操作用户无需关心。

因为邮箱在内存中实现,其空间有大小限制。其实send()和receive

()的内部实现主要还是要解决生产者与消费者问题。

【实验内容】:进程通信的邮箱方式由操作系统提供形如send()和receive()的系统调用来支持,本实验要求学生首先查找资料了解所选用操作

系统平台上用于进程通信的系统调用具体形式,然后使用该系统调

用编写程序进行进程间的通信,要求程序运行结果可以直观地体现

在界面上。在此基础上查找所选用操作系统平台上支持信号量机制

的系统调用具体形式,运用生产者与消费者模型设计实现一个简单

的信箱,该信箱需要有创建、发信、收信、撤销等函数,至少能够

支持两个进程互相交换信息,比较自己实现的信箱与操作系统本身

提供的信箱,分析两者之间存在的异同。

实验背景介绍

进程间通信有如下目的:数据的传输,共享数据,通知事情,资源共享,进程控制。进程间的通信机制(IPC),就是多进程相互通信,交换信息的方法。Linux IPC机制包括,信号和管道是其中的两个,还支持传统的UNIX SYSTM-V 的IPC 机制。

信号主要用来通知进程异步事情的发生,最初信号设计的目的是为了处理错误,他们也用来作为最基本的IPC机制。

管道是单向的,先进先出,先入先出,无结构的,固定大小的数据流。

UNIX System V 机制中的三种进程间通信机制,它们是:

消息队列:用于进程之间传递分类的格式化数据

信号量:用于通信之间的同步控制。信号量通常与共享存储器方式一起使用。共享内存:使不同进程通过共享彼此的虚拟空间而达到相互对共享区操作和数据

通信。它们之间有一个共同的特点,就是它们使用相同的认证方法,一个进程只有通过系统调用想内核传递一个唯一的引用标识符才能访问这些资源。

实验环境: ubuntu linux 操作系统

实验原理分析:

进程A 和进程B 共享内存C和D,并通过用P,V原理来控制它们对共享内存的读写。

共享内存

通过PV控制读写。信号量S0,S1,S2,S3 其中S0,S1控制C,S2,S3控制D。其中S0表示内存中有几个信息,S1表示内存还可以存几个信息。同理可得S2,S3.

PV 简略图:

进程A:

发送信息

......

P(S1)

Send ()

V(S0)

……

接受消息

……

P(S2)

Receive()

V(S3)

…….. 进程B:

发送信息

......

P(S3)

Send ()

V(S2)

……

接受消息

……

P(S0)

Receive()

V(S1)

……..

函数调用分析:共享内存的创建,读,写,删除相当于信箱的创建,收信,发

信,撤销等。共享内存区域是被多个进程共享的一部分物理内存,进程可以把这些区域映射到它们地址空间的任一适合的虚拟地址范围。这些地址范围对每一个进程来说都是不同的,映射后这些区域就可以像任何其他内存位置那样被访问,而不需要对它们使用读写调用。进程向共享内存中写入数据,那么这个区域的所有进程可以立即看见共享区的新内容。

shmget(key_t key, size_t size, int shmflg);

key标识共享内存的键值: 0/IPC_PRIVATE。当key的取值为IPC_PRIVATE,则函数shmget()将创建一块新的共享内存;如果key的取值为0,而参数shmflg中设置了IPC_PRIVATE这个标志,则同样将创建一块新的共享内存。

size是要建立共享内存的长度。

shmflg主要和一些标志有关。其中有效的包括IPC_CREAT和IPC_EXCL,它们的功能与open()的O_CREAT和O_EXCL相当。IPC_CREAT 如果共享内存不存在,则创建一个共享内存,否则打开操作。IPC_EXCL 只有在共享

内存不存在的时候,新的共享内存才建立,否则就产生错误。

成功返回共享内存的标识符;不成功返回-1,errno储存错误原因。

例如:

shmid=shmget(SHMKEY,256,IPC_CREAT|0600);

创建了一个key=SHMKEY,大小为256的共享内存。并把值给了shmid.

shmat( int shmid , char *shmaddr , int shmflag );

shmat()是用来允许本进程访问一块共享内存的函数。

int shmid是那块共享内存的ID。

char *shmaddr是共享内存的起始地址

int shmflag是本进程对该内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。其它的是读写模式

成功时,这个函数返回共享内存的起始地址。失败时返回-1

例如:addr=(char *) shmat(shmid,NULL,0);

内存地址映射把id为shmid共享内存的首地址给了addr,因此我们可以通过addr来访问共享内存,相当于,我们知道了数组的首地址,然后在对数组进行操作一样。

shmdt(Shared Memory Detach)

函数与该共享内存块脱离。将由shmat 函数返回的地址传递给这个函数。成功共时返回0,不成功返回1,注意共享内存并未删除它,只是使该共享进程当前,进程不再可用。如果当释放这个内存块的进程是最后一个使用该内存块的进程,则这个内存块将被删除。

例如:shmdt(addr);

我们有了共享内存的首地址之后,对共享内存的读写就相当于对一个数组的读写。

写:strcpy(addr,"linux"); 就把linux字符放进了共享内存。

读:printf(“%s\n”,addr);

综上所得,我们就很容易理解共享内存的一些操作;

例:

pid=shmget(Key,buffersize,IPC_CREAT|0600);//创建共享内存

char *addr;

addr=(char *)shmat(pid,NULL,0);//映射首地址

strcpy(addr," This is the message which the parent have sent!");//写共享内存

shmdt(addr);//释放共享内存

信号量:是为了控制进程对资源的使用而发明的。信号量是具有整数值的对象,它的工作原理如下;它支持两种原子操作P和V,P操作减少信号量的值,如果某一个信号量的值小于0,则操作阻塞,V操作增加信号量的值,如果结果值大于或等于0,V操作就要唤醒一个等待进程。想要获得资源时使用P操作,每次请求成功,它都要减少信号量的值,信号量的值减至0时,下一个P操作将被阻塞,释放资源的时候使用V操作,它增加信号量的值,同时唤醒被阻塞的进程。

semget( semkey, count, flag);

相关文档
最新文档