进程实验-进程间通信(管道、消息、共享内存、软中断)

2018-12-19 22:36

1

进程实验3 Linux 进程间通信

一、 软中断信号的处理,实现同一用户的各进程之间的通信。

? 相关的系统调用

? kill(pid ,sig):发送信号 ? signal(sig, func):指定进程对信号sig的处理行为是调用函数func。 ? 程序清单

#include #include #include void waiting(); void stop(); int wait_mark; main() { int p1,p2; while((p1=fork())==-1); if(p1>0) { while((p2=fork())==-1); if(p2>0) { printf(\ /*父进程在此完成某个操作、或接收到用户从键盘输入的特殊按键命令后发出下面的信号。这里省略。 */

kill(p1,16);

kill(p2,17); wait(0); wait(0); printf(\ exit(0); } else/* p2==0*/ { printf(\ wait_mark=1; signal(17,stop); waiting(); printf(\ exit(0); } } else/*p1==0*/ {

1

2

printf(\ wait_mark=1; signal(16,stop); waiting(); printf(\ exit(0); } }

void waiting()

{while(wait_mark!=0);} void stop()

{wait_mark=0;}

? 输入并运行此程序,分析程序的运行结果。

二、 消息的创建、发送和接收

? 多个进程通过访问一个公共的消息队列来交换信息 ? 消息队列:

即消息的一个链表

? 任何进程都可以向消息队列中发送消息(消息类型及正文),其它进程都可以从消息队列中根据类型获取相应的消息

? 相关的系统调用 头文件:#include

? 打开或创建消息队列:int msgget(key_t key, int msgflg);

? key:消息队列的键

? IPC_PRIVATE: 创建一个私有的消息队列 ? 其它:可被多个进程使用的消息队列

? msgflg:设置操作类型及访问权限IPC_CREAT / IPC_EXCL

? 获得或设置消息队列属性:int msgctl( int msgid, int cmd, struct msqid_ds

*data);

? 发送消息:int msgsnd(int msgid, const void *msgp,

size_t msgsize, int flags); ? 参数

? msgid:消息队列标识符id

? msgp:指针,用户自定义缓冲区,可定义成结构体类型,包含两项

long mtype;代表消息类型

char mtext[MTEXTSIZE];消息正文 ? msgsize:要发送消息正文的长度

? mflags:标志,若设置IPC_NOWAIT则不等待

消息发出就返回

? 返回值:成功返回0,错误返回-1(置errno)

? 接收消息int msgrcv(int msgid, void *msgp, size_t mtexsize, long msgtype,

int flags);

2

3

? 参数:与msgsnd类似

? msgtype

? >0:只接收指定类型消息的第一个

? ==0:不管什么消息类型都读取队列中第一个数据

? <0:接收等于或小于其绝对值的最低类型的第一个,如有5、

6、17三类,若为-6,则获取类型5的。

? 返回值

? 成功:返回消息正文字节数 ? 错误:返回-1(置errno)

? 程序清单

#include #include #include #include #define MSGKEY 75 struct msgform {

long mtype;

char msgtext[1030]; }msg;

int msgqid,i; void CLIENT() {

int i; char string_i[5];

msgqid=msgget(MSGKEY,0777); for(i=10;i>=1;i--) {

msg.mtype=i;

printf(\

sprintf(msg.msgtext,\ message \ sprintf(string_i, \ strcat(msg.msgtext,string_i); strcat(msg.msgtext,\

msgsnd(msgqid,&msg,1030,0); }

exit(0); }

void SERVER() {

msgqid=msgget(MSGKEY,0777|IPC_CREAT); do { msgrcv(msgqid,&msg,1030,0,0); printf(\

3

4

printf(“%s\\n\ }while(msg.mtype!=1);

msgctl(msgqid,IPC_RMID,0); exit(0); }

main() {

while((i=fork())==-1); if(!i) SERVER();

while((i=fork())==-1); if(!i) CLIENT(); wait(0); wait(0); }

编辑并运行程序,并分析程序的运行结果。 思考题:符号常量MSGKEY有什么作用?server和client不使用同一个MSGKEY会出现什么问题?

程序扩展:client和server之间怎样通过软中断信号控制进程的推进速度,使得client每发送一个消息,server就接收一个消息,然后client再发送下一个消息?

三、 共享存储区的创建、发送和接收

同一系统中的几个进程可共享某块物理内存。include

? 打开或创建创建共享区:int shmget(key_t key, size_t size, int shmflg);

? 参数

? key:键值 ? IPC_PRIVATE: 创建一个私有的shm ? 其它:非IPC_PRIVATE整数值。 ? size:指明shm的大小,若shm已经存在,则size应为0 ? shmflg:设置访问权限及IPC_CREAT / IPC_EXCL ? 返回值

? 成功:该shm的id,当前进程是其 拥有者及创建者

错误:-1

? 将共享内存连接到进程中:void *shmat(int shmid, const void *shmaddr, int flags);

? 参数

? shmid:共享内存标识符id ? shmaddr:进程映射内存段的地址,可指定,但一般设为NULL表示

由系统安排。 ? flags:对该内存的段设置是否只读 (SHM_RDONLY),

默认是读写。

? 返回值

? 成功:进程中该内存段的地址 ? 错误: -1

4

? 程序清单:

#include #include #include #include #define SHMKEY 75

int shmid,i; int *addr;

void CLIENT() {

int i;

shmid=shmget(SHMKEY,1024,0777); addr=shmat(shmid,0,0); for(i=5;i>=0;i--) { while(*addr!=-1); printf(\ *addr=i;

printf(\ }

exit(0); }

void SERVER() {

shmid=shmget(SHMKEY,1024,0777|IPC_CREAT); addr=shmat(shmid,0,0); do { *addr=-1; while(*addr==-1); printf(\ printf(\ }while(*addr);

shmctl(shmid,IPC_RMID,0); exit(0); }

main()

5

5

6

{

while((i=fork())==-1); if(!i)SERVER();

while((i=fork())==-1); if(!i) CLIENT(); wait(0); wait(0); }

编辑并运行程序,并分析程序的运行结果。

在此基础上对程序进行修改:使得每次循环中:CLIENT向共享区发送10个整数, SERVER从共享区接收10个整数、并输出。

6


进程实验-进程间通信(管道、消息、共享内存、软中断).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:IFIX教程之使用VX控件

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: