操作系统实验 进程通信

上传人:z*** 文档编号:61292274 上传时间:2022-03-11 格式:DOC 页数:9 大小:521KB
返回 下载 相关 举报
操作系统实验 进程通信_第1页
第1页 / 共9页
操作系统实验 进程通信_第2页
第2页 / 共9页
操作系统实验 进程通信_第3页
第3页 / 共9页
点击查看更多>>
资源描述
进程通信(实验二)【实验目的】:掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。【实验原理】:邮箱机制类似于日常使用的信箱。对于用户而言使用起来比较方便,用户只需使用send()向对方邮箱发邮件 receive()从自己邮箱取邮件, send()和 receive()的内部操作用户无需关心。因为邮箱在内存中实现,其空间有大小限制。其实send()和 receive()的内部实现主要还是要解决生产者与消费者问题。进程A进程B信箱A信箱BSend()Send()receive()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(“%sn”,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); 其中semkey 和flag 类似于建立消息和共享存储区域,semkey是用户指定的关键字,count 是指定信号量数组的长度。Semid=(senkey ,4,0777|IPC_CREAT);创建了一个关键字为semkey的含有4个元素的信号量数组。注意信号量数组序号是从0才是编址。semop(semid, struct sembuf semoparray, size_t nops ); 函数中参数semid是一个通过semget函数返回的一个信号量标识符,参数nops标明了参数semoparray所指向数组中的元素个数。参数semoparray是一个struct sembuf结构类型的数组指针,结构sembuf来说明所要执行的操作,其定义如下: struct sembuf unsigned short sem_num; /信号量集中的某一个信号量short sem_op; / sem_op指明所要执行的操作(1表示V操作,-1表示P操作)short sem_flg; 例:Int P(int semid)struct sembuf p; P.sem_num=1;/对第二个信号量; P.sem_op=-1;/p操作; P.sem_flag=SEM_UNDO; semop(semid,&p,1);Int V(int semid)struct sembuf p; P.sem_num=2;/对第三个信号量; P.sem_op=1;/V操作; P.sem_flag=SEM_UNDO; semop(semid,&p,1);对信号量进行控制semctl(int semid,int num,int cmd,union arg); 系统调用semctl()的semid参数是关键字值。第二个参数是信号量数目。参数cmd中可以使用的命令中SETVAL设置信号量集中的一个单独的信号量的值。返回值:如果成功,则为一个正数。如果失败,则为-1union semun int val; struct semid_ds *buf; unsigned short *array; sem;sem.val=0;/设置初值为0;semctl(sem_id,0,SETVAL,sem);/对第一个信号量设置初值为0;综上所得涉及到我们需要了全部调用函数,只要将这些函数合理的组合在一起,就得到了我们想要的实验效果了。实验调试过程:创建共享内存和信号量以及初始状态A发送信息到共享内存C,相当于A给B发送邮件B从共享内存C中读取信息,相当于接受了邮件并查看了 同理可得实验扩展:由实验的PV控制可知,当进程A的发送信息被挂起时,下面的进程B 收信息也被挂起时。不符合常理,若调用了fork()函数,进程A又分为父进程和子进程与题意不符。故可引进线程,线程1为收信息,线程2为发信息。调用函数:int pthread_creat(pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void*),void *arg);/创建线程void pthread_exit(void * retval);/结束线程int pthread_join(pthread_t th,void * thread_return) /线程挂起 附:mailA代码
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 商业管理 > 营销创新


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!