4444444

一【实验目的】

1.理解进程间通信原理;

2.掌握进程中信号量、共享内存、消息队列相关的函数的使用;

3.支撑网络空间安全专业的专业核心能力、综合创新能力。

二【实验要求】

以下每个实验均要求:

1.“实验源代码”处:粘贴所编写的程序源码,务必添加关键语句的注释;

2.“实验结果”:截图(包括编写的程序和运行结果)粘贴到“实验结果”下方,截图需看到本人的名字及学号;

3.有“讨论”的题目,请务必认真回答;

三【实验内容】

4-1 编写程序实现以下功能:

利用匿名管道实现父子进程间通信,要求

父进程发送字符串“hello child”给子进程;

子进程收到父进程发送的数据后,给父进程回复“hello farther”;

父子进程通信完毕,父进程依次打印子进程的退出状态以及子进程的pid。

【源代码】

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/wait.h>

int main() {

         int fd1[2],fd2[2];

         pipe(fd1);

         pipe(fd2);

         int pid;

         pid = fork();

         if(pid < 0)

                   perror("fork");

         else if(pid == 0) {

                   close(fd1[0]);

                   close(fd2[1]);

                   char str[12];

                   printf("This is the child!\n");

                   if(read(fd2[0],str,12) > 0) {

                            printf("Received the news: %s\n",str);

                            if(write(fd1[1],"hello father",12) < 0)

                                     perror("write");

                   } else

                            perror("read");

                   exit(5);

         } else {

                   int status;

                   printf("This is the father!\n");

                   close(fd1[1]);

                   close(fd2[0]);

                   char buf[24] = "hello child";

                   if(write(fd2[1],buf,12) < 0)

                            perror("write");

                   else {

                            printf("Send news successful!\n");

                   }

                   wait(&status);

                   if(WIFEXITED(status)) {

                            printf("The child's pid is: %d\n",pid);

                            printf("The child's exited status is: %d\n",WEXITSTATUS(status));

                   }

         }

         return 0;

}

4-2 编写程序实现以下功能:利用匿名管道实现兄弟进程间通信,要求兄进程发送字符串“This is elder brother ,pid is (兄进程进程号)”给弟进程;弟进程收到兄进程发送的数据后,给兄进程回复“This is younger brother ,pid is(第进程进程号)”;

实验步骤:父进程先创建一个子进程(这个就是兄进程) 然后通过判断进入父进程中,然后再次创建一个进程 这个进程就是弟进程 父进程先创建一个子进程(这个就是兄进程) 然后通过判断进入父进程中,然后再次创建一个进程 这个进程就是弟进程。

【源代码】

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/stat.h>

int main() {

         int fd1[2],fd2[2];

         pipe(fd1);

         pipe(fd2);

         int pid;

         pid = fork();

         if(pid == 0) {

                   printf("This is the elder brother!\n");

                   printf("The elder's father's pid is: %d\n",getppid());

                   close(fd1[1]);

                   close(fd2[0]);

                   char str1[64],str2[64];

                   sprintf(str1,"This is the elder brother,pid is %d",getpid());

                   if(write(fd2[1],str1,64) < 0)

                            perror("write");

                   if(read(fd1[0],str2,64) < 0)

                            perror("read");

                   else

                            printf("The news from younger is: %s\n",str2);

         } else {

                   if(fork() == 0) {

                            printf("This is the younger brother!\n");

                            printf("The younger's father's pid is: %d\n",getppid());

                            close(fd1[0]);

                            close(fd2[1]);

                            char buf1[64],buf2[64];

                            if(read(fd2[0],buf1,64) > 0) {

                                     printf("The news form elder is: %s\n",buf1);

                                     sprintf(buf2,"This is the younger brother,pid is %d",getpid());

                                     if(write(fd1[1],buf2,64) < 0)

                                               perror("write");

                            } else

                                     perror("read");

                   }

         }

}

4-3 编写程序实现以下功能:

利用有名管道文件实现进程间通信,要求

写进程向有名管道文件写入10次“hello world”;

读进程读取有名管道文件中的内容,并依次打印。

【源程序】

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <unistd.h>

#include <sys/stat.h>

int main() {

         int pid,fd,i;

         if(mkfifo("fifotest",0666) < 0)

                   perror("mkfifo");

         pid = fork();

         if(pid < 0)

                   perror("fork");

         else if(pid == 0) {

                   printf("This is the write process!\n");

                   int fd = open("fifotest",0666);

                   for(i = 0; i < 10; i++) {

                            if(write(fd,"hello world",12) < 0)

                                     perror("write");

                            sleep(1);

                   }

                   close(fd);

         } else {

                   char str[128];

                   printf("This is the read process!\n");

                   int fd1 = open("fifotest",0666);

                   for(i = 0; i < 10; i++) {

                            if(read(fd1,str,128) < 0)

                                     perror("read");

                            else

                                     printf("%s\n",str);

                   }

                   system("rm -f fifotest");

         }

}

4-4 编写代码完成以下功能:

创建共享内存,写进程通过键盘不断向内存写入“hello world”;

如果结束写操作,则通过键盘输入“end”;

读进程从共享内存读取数据,并打印。直到读到“end”为止。

【源程序】

4.4.read.c

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/shm.h>

#define MAXSIZE 1024

struct shm {

         int write;   

         char buffer[MAXSIZE];

};

int main() {

         int shmid;

         struct shm *share;

         void *shmptr = NULL;

         if((shmid = shmget(0X44,MAXSIZE,0666|IPC_CREAT)) < 0)

                   perror("shmget");

         if((shmptr = shmat(shmid,0,0)) == (void *)-1)

                   perror("shmat");

         printf("This is the read process!!!\n");

         share = (struct shm *)shmptr;

         while(1) {

                   if(share->write != 0) {

                            if(!strncmp(share->buffer,"end",3) == 0) {

                                     printf("%s",share->buffer);

                                     share->write = 0;

                            } else

                                     break;

                   }

         }

         if(shmdt(shmptr) < 0)

                   perror("shmdt");

         exit(0);

}

4.4.write.c:

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <sys/shm.h>

#define MAXSIZE 1024

struct shm {

         int write;        //记录读进程是否已经将内容读取

         char buffer[MAXSIZE];

};

int main() {

         int shmid;

         void *shmptr = NULL;

         char str[MAXSIZE];    //存储输入的内容

         struct shm *share;

         if((shmid = shmget(0X44,MAXSIZE,0666|IPC_CREAT)) < 0)

                   perror("shmget");

         if((shmptr = shmat(shmid,0,0)) == (void *)-1)

                   perror("shmat");

         printf("This is the write process!!!\n");

         share = (struct shm *)shmptr;

         while(1) {

                   if(share->write == 1) {

                            sleep(1);

                            printf("Waiting the read process!!!\n");

                   }

                   printf("please input hello world!!!\n");

                   fgets(str,MAXSIZE,stdin);

                   sprintf(share->buffer,"%s",str);

                   share->write = 1;

                   if(strncmp(str,"end",3) == 0)

                            break;

                   sleep(1);

         }

         if(shmdt(shmptr) < 0)

                   perror("shmdt");

         exit(0);

}

4-5 编写代码完成以下功能:

进程A向消息队列发送消息“hello,world”

进程B从消息队列读取消息,并打印。

进程C向消息队列发送“自己在姓名”

进程D从消息队列中取出姓名字符串,并打印

消息队列也叫报文队列,是一个消息的链表。可以把消息看作是一个记录,具有特定的格式以及优先级。对消息队列具有写权限的进程可以按照一定的规则向消息队列中添加消息,而对消息队列具有写权限的进程可以从消息队列中读走消息。和管道相似的是,消息一旦从消息队列中被读走,则消息队列中便不在存在此条消息。

#include <stdio.h>

#include <stdlib.h>

#include <sys/ipc.h>

#include <unistd.h>

#include <sys/msg.h>

#include <sys/types.h>

struct msg {

         char msg_str[128];

};

int main() {

         int qid;

         struct msg mymsg;

         if(qid = msgget(0x66,0666|IPC_CREAT) < 0)

                   perror("msgget");

         int pid;

         pid = fork();

         if(pid < 0)

                   perror("fork");

         else if(pid == 0) {

                   printf("This is A process!\n");

                   sprintf(mymsg.msg_str,"hello world");

                   if(msgsnd(qid,&mymsg,128,0) < 0)

                            perror("msgsnd");

         } else {

                   if(fork() == 0) {

                            printf("This is B process!\n");

                            if(msgrcv(qid,&mymsg,128,0,0) < 0)

                                     perror("msgrcv");

                            printf("The msg is: %s\n",mymsg.msg_str);

                   } else if(fork() == 0) {

                            printf("This is the C process!\n");

                            sprintf(mymsg.msg_str,"Mamingyuan");

                            if(msgsnd(qid,&mymsg,128,0) < 0)

                                     perror("msgsnd");

                   } else {

                            printf("This is D process!\n");

                            if(msgrcv(qid,&mymsg,128,0,0) < 0)

                                     perror("msgrcv");

                            printf("The msg is: %s\n",mymsg.msg_str);

                   }

         }

         return 0;

}

补充知识:IPC消息队列的缺省最大数为16;每个消息缺省最大值为8192字节;队列中的最大值缺省为16384字节;每个消息队列都有其对应的属性信息,存储在struct_msqid_ds结构体中。每个消息队列都有一个对应的id,标识消息队列的唯一性。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

m0_57872164

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

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

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

打赏作者

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

抵扣说明:

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

余额充值