Linux进程间通信

本文介绍了一个基于Linux系统进程间通信(IPC)的实验设计,包括消息队列与共享内存的创建、使用及管理过程。实验通过父进程fork出SERVER与CLIENT两个子进程,实现了消息的发送接收及共享内存数据交换。
摘要由CSDN通过智能技术生成

一、实验目的

    Linux 系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据,通过本实验,理解熟悉 Linux 支持的消息通信机制、共享存储区机制及信息量机制。 

二、总体设计

2.1背景知识

系统调用函数说明、参数值及定义
l  fork( )
    创建一个新进程。
    int fork( )
    其中返回 int 取值意义如下:
    0:创建子进程,从子进程返回的 id
    大于 0:从父进程返回的子进程 id
    -1:创建失败
    UINX/Linux 系统把信号量、消息队列和共享资源统称为进程间通信资源(IPC resource)。提供给用户的 IPC 资源是通过一组系统调用实现的。这组系统调用为用户态进程提供了以下三种服
务:

用信号量对进程要访问的临界资源进行保护。

用消息队列在进程间以异步方式发送消息。

用一块预留出的内存区域供进程之间交换数据。
    ●创建 IPC 资源的系统调用有:

semget()—获得信号量的 IPC 标识符。

msgget()—获得消息队列的 IPC 标识符。

shmget()—获得共享内存的 IPC 标识符。
    ●控制 IPC 资源的系统调用有:

 semctl()—对信号量资源进行控制的函数。

msgctl()—对消息队列进行控制的函数。

shmctl()—对共享内存进行控制的函数。
    上述函数为获得和设置资源的状态信息提供了一些命令。例如:

IPC_SET 命令:设置属主的用户标识符和组标识符。

IPC_STAT IPC_INFO 命令:获得资源状态信息。

IPC_RMID 命令:释放这个资源。
    ●操作 IPC 资源的系统调用有:
    semop()—获得或释放一个 IPC 信号量。 可以实现 PV 操作

msgsnd()—发送一个 IPC 消息。

msgrcv()—接收一个 IPC 消息。

shmat()—将一个 IPC 共享内存段添加到 进程的地址空间

shmdt()——将 IPC 共享内存段从私有的地址空间剥离 

2.2 设计步骤

1)任务 1(消息的创建、发送和接收)的程序设计

1) 为了便于操作和观察结果,用一个程序作为“引子”,先后 fork()两个子进程 SERVERCLIENT,进行通信。
2SERVER 端建立一个 key 75 的消息队列,等待其他进程发来的消息。当遇到类型为 1 的消息,则作为结束信号,取消该队列,并退出 SERVERSERVER 每接收到一个消息后显示一句“(serverreceived”。
3CLIENT 端使用 key 75 的消息队列,先后发送类型从 10 1 的消息,然后退出。最后的一个消息,即是 SERVER 端需要的结束信号。 CLIENT 每发送一条消息后显示一句“(client)sent”。
4) 父进程在 SERVER CLIENT 均退出后结束。
2)任务 2(共享存储区的创建、附接和断接)的程序设计
1) 为了便于操作和观察结果,用一个程序作为“引子”,先后 fork()两个子进程 SERVERCLIENT,进行通信。
2SERVER 端建立一个 key 75 的消息队列,并将第一个字节置为-1,作为数据空的标志,等待其他进程发来的消息。当该字节的值发生变化时,表示收到了信息,进行处理。然后再次把它的值设为-1。当遇到的值为 0,则视为结束信号,取消该队列,并退出 SERVERSERVER 每接收到一个消息后显示一句“(serverreceived”。
3CLIENT 端使用 key 75 的消息队列,当共享取得第一个字节为-1 时, SERVER端空闲,可发送请求。 CLIENT 随即填入 9 0。期间等待 SERVER 端的再次空闲。进 行 完 这 些 操 作 后 , CLIENT 退 出 。 CLIENT 每 发 送 一 条 消 息 后 显 示 一 句“(client)sent”。
4) 父进程在 SERVER CLIENT 均退出后结束。

三、详细设计

任务一代码:

#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define MSGKEY 75
struct msgform
{
long mtype;
char mtext[1030];
}msg;
int msgqid,i;
void CLIENT()
{
int i;
msgqid=msgget(MSGKEY,0777);
for (i=10;i>=1;i--)
{
msg.mtype=i;
printf("(client) sent \n");
msgsnd(msgqid,&msg,1024,0);
}
exit(0);
}
void SERVER()
{
msgqid=msgget(MSGKEY,0777|IPC_CREAT);
do{
msgrcv(msgqid,&msg,1030,0,0);
printf("(Server) recieved\n");
} while(msg.mtype!=1);
msgctl(msgqid,IPC_RMID,0);
exit(0);
}
int main()
{
while((i=fork())==-1);
if(!i) SERVER();
while((i=fork())==-1);
if(!i) CLIENT();
wait(0);
wait(0);
}

任务二代码:

#include <stdio.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define MSGKEY 75
int shmid,i;
int *addr;

void CLIENT()
{
  int i;
  shmid=shmget(MSGKEY,1024,0777);
  addr=shmat(shmid,0,0);
for (i=9;i>=0;i--)
{
   while(*addr!=-1);
   printf("(CLIENT) sent\n");
   *addr=i;
}
exit(0);
}
void SERVER()
{
   shmid=shmget(MSGKEY,1024,0777|IPC_CREAT);
   addr=shmat(shmid,0,0); //shoudizhi
do{
   *addr=-1;
   while(*addr==-1);
   printf("(Server) recieved\n");
} while(*addr);
  shmctl(shmid,IPC_RMID,0);
  exit(0);
}
int main()
{
while((i=fork())==-1);
if(!i) SERVER();
while((i=fork())==-1);
if(!i) CLIENT();
wait(0);
wait(0);
}

四、实验结果与分析

任务一:

消息的传送和控制并不保证完全同步,当一个个程序不在激活状态的

时候,它完全可能继续睡眠,造成了出现几个“( client) sent”连续后再几个“( server) received”,现象。实验结果如下:

 

任务二:

两种消息传送机制对比:

消息队列的建立比共享区的设立消耗的资源少。

消息队列由软件控制和实现,共享区的数据传输受硬件限制。

共享区的数据传输运行结果如下:


五、小结与心得体会

   通过本实验,理解熟悉 Linux 支持的消息通信机制、共享存储区机制及信息量机制。 Linux 系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的书包哪里去了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值