1、熟悉操作系统进程通信原理。
2、设计程序,实现共享内存、管道通信、消息通信。
1、进程间通信的几种方法简介。
1)消息队列:消息队列是消息的链接表,包括posix消息队列systemv消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
2)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用ipc形式。是针对其他通信机制运行效率较低而设计的。
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
3)无名管道(pipe)及有名管道(named pipe):有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;无名管道可用于有亲缘关系的进程之间彼此的通信,进行通信时候必须有一定的机制保证对管道写和读的互斥:即在读是要关闭写的端口,而在写的时候也要保证读的一端是关闭的。
2、进程通信函数。
1)消息队列有关系统调用函数。
a.创建消息队列使用msgget()函数:
#include
#include
#include
int msgget(key_t key, int flag) ;
该函数成功调用返回消息队列标识符。其中的key是关键字,可以由ftok()函数得到:
key=ftok(“.a’);
其中”.”可以是任何目录,’a’是任意字符,即所有群组标识。
flag是标识,ipc_creat位表示创建,一般由服务器程序创建消息队列时使用。如果是客户程序,必须打开现存的消息队列,必须不使用ipc_creat。
发送和接收的消息都必须使用一个类似msgbuf的结构表示,msgbuf结构定义如下:
struct msgbuf
long mtype;
char mtext[1];
上面的定义,消息内容只有一个字节,是不实用的,一般我们需要重新定义一个结构:
struct amsgbuf
long mtype;
char mtext[200];
其中的mtype都是消息类型。
b.发送消息实用msgsnd()函数:
#include
#include
#include
int msgsnd(int msqid,const void * ptr, size_t nbytes, int flag);
msqid是消息队列标识符,ptr是消息结构的指针,nbytes是消息结构中消息的长度,flag是标识,如果是0,可以有效的关闭错误检查。如:
struct amsgbuf mymsg;
sprintf( is test”);
/向内存写入,为内存地址。
msgsnd(msqid, &mymsg,sizeof(“this is test”)+1,0);
c.接收消息用函数msgrcv():
#include
#include
#include
int msgrcv(int msqid,void *ptr, size_t nbytes,long type,int flag);
参数type给出希望接收消息的类型,如果指定非0的值,则必须返回指定的类型消息。如果取任意类型的消息,那么让type为0就可以了。其它参数和msgsnd()相同。如:
struct amsgbuf mymsg;
msgrcv(msqid, &mymsg,80,125 ,ipc_nowait);
指定ipc_nowait是希望没有消息可供获取时立即返回。
2)systemv共享内存:
a. int shmget(key_t key,int size,int shmflg);
该函数会在内存中创建一个指定大小的共享缓冲区,并返回缓冲区的id标识值。
若失败则返回-1.
key:系统关键字,一般用ipc_private。
size:指定缓冲区大小。
shmflg:共享标志,一般用0。
用法:shmid=shmget(ipc_private,1024,0);
创建一个1k的共享缓冲区。
b. void *shmat(int shmid,const void *shmaddr,int shmflg);
该函数会得到共享缓冲区的入口地址,保存在shmaddr中。
shmid:共享缓冲区的id标识值。
shmaddr:保存缓冲区的入口地址。
shmflg:共享标志,一般为0。
普遍用法:paddr=shmat(shmid,0,0);
取缓冲区shmid的入口,到paddr中。
shmdt(const void *shmaddr);
断开共享缓冲区的连接,用于关闭入口。
shmaddr:缓冲区入口。
用法:shmdt(paddr);
关闭缓冲区入口paddr。
该方法有一不足的地方,就是共享区开辟后,必须手动释放开辟的空间。
用ipcs查看开辟共享区的id,用 ipcrm shm shmid释放空间。
//创建删除共享存储区(指出创建共享存储区的名字和长度):主要由存储器管理模块完成。
//共享存储区的附接与断开(附接即把共享存储区映射到进程的虚空间):附接后进程可以象访问虚空间一样访问共享存储区。
//共享存储区状态查询(查询设置的参数)
//共享存储区管理(os应当具有相应的管理**)p(1)
shmid=shmget(shmkey,16*k,0777|ipc_creat);
/调用创建共享存储区系统调用,shmkey为名字,16*k为长度,返回共享区的编号送shmid
addr=shmat(shmid,0,0) ;调用附接函数,返回首址。
pint=(int)*addr获得共享区的首地址。
for(i=0;i<256;i++)
*pint++=i向共享区写入0,1,2
pause等待接受者读共享区。
p(2)
shmid2=shmget(shmkey,16*k,0777);
//创建共享区。
addr2=shmat(shmid2,0,0); 附接。
pint2=(int*)addr2; /获取共享区的收地址。
while(*pint2==0)//循环等待,直到第一个字节不为0为止
for(i=0;i<256;i++)
printf(“%d”,*pint2++)
使用shmdt从共享区域中分离
3)管道的读写规则。
无名管道:
a) who|
b)使用管道创建原语pipe()创建,或者popen()创建,当进程结束时,管道就自动消亡。只适用于相互关联的进程。
int pipe(int fildes[2]);
pipe调用可以创建一个管道(通信缓冲区).当调用成功时,管道两端可分别用描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。
如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生。一般文件的i/o函数都可以用于管道,如close、read、write等等。
从管道中读取数据:
如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;
有名管道(也称fifo文件):
由专门的文件创建命令创建,与普通文件一样,有文件主、创建时间等信息,普通文件操作命令open等也适用于它。可以被无关的进程使用。
%mknod pipe(文件名) p(参数,创建命名管道文件)
%ls –l pipe
%cat test_ >pipe //显示内容被重定向到命名管道pipe中。
%cat mknod系统调用
1、下面的程序由父进程从命令行输入要传递的字符串,子进程接受这些字符串并且将其以单词的形式显示出来。
#include <>
#include <>
#include <>
#include <>
#include
#include <>
int main(int argc,char **ar**)
int pipe_fd[2];/无名管道标示符。
pid_t pid;//进程号用以区分是父进程还是子进程。
char r_buf[11];/用于向管道写的数组。
char w_buf[argc][11];/用于向管道读的数组。
int i;
memset(r_buf,0,sizeof(r_buf));将写的字符数组清0
memset(w_buf,0,sizeof(r_buf));将读的字符数组清0
if(pipe(pipe_fd)<0)//创建不成功。
if((pid=fork())0)//子进程。
printf("");
close(pipe_fd[1]);关闭写端口。
sleep(2);/等待关闭完成
for(i=0;i
read(pipe_fd[0],r_buf,10);
从端口中读出10个字符
实验3Linux进程通信
printf client sent msgsnd msgqid,msg,1024,0 发送消息msg入msgqid消息队列 exit 0 结束该进程。void server while 消息类型为1时,退出循环 msgctl msgqid,ipc rmid,0 释放 删除 消息队列 exit 0 ...
实验4进程调度
实验4 进程调度算法实验。4.1实验目的与要求 通过了解在真实的操作系统中它是怎样实现教材中讲解的进程调度效果的,加深对进程调度概念的理解,体验进程调度机制的功能 了解linux系统中进程调度策略的使用方法,练习进程调度算法的编程和调试技术。根据示例程序和独立实验程序中观察和记录的信息及其结果分析写...
实验4进程管理
实验 程管理 进程互斥与同步实验。实验目的。1 进一步认识并发执行的实质。2 分析进程竞争资源的现象,学习解决进程互斥的方法。3 掌握用linux信号灯集机制实现两个进程间的同步问题。实验内容。调试运行程序,观察并分析出现的现象。实验指导。一 所涉及的系统调用。lockf files,functio...