实验 进程通信【操作系统】

简介: 实验 进程通信【操作系统】

推荐

linux 进程间通信三 消息队列以及实例

【Linux】消息队列–实现进程间通信

进程间通信具体实现代码(两个程序间互发信息)

实例1

实例1:一个程序,自己发消息,然后自己再从队列上读消息

代码

msgque.c

/*msgque.c*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define  BUFSZ    512
struct message
{
  long msg_type;
  char msg_text[BUFSZ];
};
int main()
{
  int qid;
  key_t key;
  int len;
  struct message msg;
  /*根据不同的路径和关键表示产生标准的key*/
  if ((key = ftok(".", 'a')) == -1)
  {
    perror("ftok");
    exit(1);
  }
  /*创建消息队列*/
  if ((qid = msgget(key,IPC_CREAT|0666)) == -1)
  {
    perror("msgget");
    exit(1);
  }
  printf("Opened queue %d\n",qid);
  puts("Please enter the message to queue:");
  if ((fgets((&msg)->msg_text, BUFSZ, stdin)) == NULL)   //消息内容
  {
    puts("no message");
    exit(1);
  }
  msg.msg_type = getpid();                       //消息类型,可以理解为发信人名字
  len = strlen(msg.msg_text);
  /*添加消息到消息队列*/
  if ((msgsnd(qid, &msg, len, 0)) < 0)           //把消息加到队列
  {
    perror("message posted");
    exit(1);
  }
  /*读取消息队列*/
  if (msgrcv(qid, &msg, BUFSZ, getpid(), 0) < 0)     //读发信人为getpid()的消息
  {
    perror("msgrcv");
    exit(1);
  }
  printf("message is:%s\n",(&msg)->msg_text);
  /*从系统内核中移走消息队列 */
  if ((msgctl(qid, IPC_RMID, NULL)) < 0)
  {
    perror("msgctl");
    exit(1);
  }
  exit(0);
}

结果



实例2

实例2:一个程序发送消息 ,另一个接收消息,读的是第一条消息不判断是不是自己想要的消息

代码

msgsnd.c

/* msgsnd.c */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define  BUFFER_SIZE 512
struct message
{
    long msg_type;
    char msg_text[BUFFER_SIZE];
};
int main()
{
int qid;
key_t key;
struct message msg;
/*根据不同的路径和关键表示产生标准的key*/
if ((key = ftok(".", 'a')) == -1)
{
    perror("ftok");
    exit(1);
}
/*创建消息队列*/
if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
{
    perror("msgget");
    exit(1);
}
printf("Open queue %d\n",qid);
while(1)
{
   printf("Enter some message to the queue(enter 'quit' to exit):");
    if ((fgets(msg.msg_text, BUFFER_SIZE, stdin)) == NULL)
    {
        puts("no message");
        exit(1);
    }
msg.msg_type = getpid();
/*添加消息到消息队列*/
if ((msgsnd(qid, &msg, strlen(msg.msg_text), 0)) < 0)
{
perror("message posted");
exit(1);
}
if (strncmp(msg.msg_text, "quit", 4) == 0)
{
break;
}
}
exit(0);
}

msgrcv.c

/* msgrcv.c */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define  BUFFER_SIZE    512
struct message
{
  long msg_type;
  char msg_text[BUFFER_SIZE];
};
int main()
{
  int qid;
  key_t key;
  struct message msg;
  /*根据不同的路径和关键表示产生标准的key*/
  if ((key = ftok(".", 'a')) == -1)
  {
    perror("ftok");
    exit(1);
  }
  /*创建消息队列*/
  if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
  {
    perror("msgget");
    exit(1);
  }
  printf("Open queue %d\n", qid);
  do
  {
    /*读取消息队列*/
    memset(msg.msg_text, 0, BUFFER_SIZE);
    if (msgrcv(qid, (void*)&msg, BUFFER_SIZE, 0, 0) < 0)   //读取消息不管是谁发的
    {
      perror("msgrcv");
      exit(1);
    }
    printf("The message from process %d : %s", msg.msg_type, msg.msg_text);   
  } while(strncmp(msg.msg_text, "quit", 4));
  /*从系统内核中移走消息队列 */
  if ((msgctl(qid, IPC_RMID, NULL)) < 0)
  {
    perror("msgctl");
    exit(1);
  }
  exit(0);
}

结果



实例3

进程间通信具体实现代码(两个程序间互发信息)

设计两个程序,要求用消息队列实现聊天程序。

输入bye,结束聊天

代码

comm.h

#ifndef _COMM_H_
#define _COMM_H_
#include <stdio.h>
#include <sys/types.h>  
#include <sys/ipc.h>  
#include <sys/msg.h>  
#include <string.h>
#define SERVER 1 
#define CLIENT 2
#define PATHNAME "."
#define PROJ_ID 0x6666
struct msgbuf{
  long mtype;
  char mtext[1024];
};
int creat();//创建消息队列
int send(int msgid,int who,char *msg);  //发送消息  
int recv(int msgid, int type, char out[]);//接收消息  
int destory(int msgid);//销毁消息队列
int get();//获得消息队列的标识符 
#endif

comm.c

#include "comm.h"
static int com(int flags){
  key_t key=ftok(PATHNAME,PROJ_ID);  
  if(key<0){
    perror("ftok");
    return -1;
  }
  int msgid=msgget(key,flags);
  if (msgid<0){
    perror("msgget");  
    return -2;
  }
  return msgid;
}
int creat(){
  return com(IPC_CREAT|IPC_EXCL|0666);
}
int destory(int msgid){
  if(msgctl(msgid,IPC_RMID,NULL)<0){
    perror("msgctl");
    return -1;
  }
}
int get(){
  return com(IPC_CREAT);
}
int send(int msgid,int who,char*msg){
  struct msgbuf buf;
  buf.mtype=who;
  strcpy(buf.mtext,msg);
  if(msgsnd(msgid,(void*)&buf,sizeof(buf.mtext),0)<0) {
    perror("msgsnd");
    return -1;
  } 
}  
int recv(int msgid,int type,char out[]){
  struct msgbuf buf;
  if(msgrcv(msgid,(void*)&buf,sizeof(buf.mtext),type,0)<0){
    perror("msgrcv");
    return -1;
  } 
  strcpy(out,buf.mtext);
  return 0;
}

server.c

#include"comm.h"
int main(){
  int msgid=creat();
  char buf[1024];
  while(1){
    buf[0]=0;
    recv(msgid,CLIENT,buf);
    printf("client say #%s\n",buf);
    if(strcmp(buf,"bye\n")==0){ 
      printf("通信结束\n"); 
      break;    
    }
    printf("please enter#");
    fflush(stdout);
    ssize_t s=read(0,buf,sizeof(buf)-1);  
    if(s>0){
      buf[s]=0;
      send (msgid,SERVER,buf);
    }
  }
  destory(msgid);
  return 0;
}

client.c

#include"comm.h"
int main(){
  int msgid=get();
  char buf[1024];
  while(1){
    buf[0]=0;
    printf("please enter#");
    fflush(stdout);
    ssize_t s=read(0,buf,sizeof(buf)-1);  
    if(s>0){
      buf[s]=0;
      send (msgid,CLIENT,buf);
    }
    recv(msgid,SERVER,buf);
    printf("server say #%s\n",buf);
    if(strcmp(buf,"bye\n")==0){
      printf("通信结束\n");
      break;    
    }
  }
  destory(msgid);
  return 0;
}

Makefile

.PHONY:all
all:server client
server:server.c comm.c
  gcc -o $@ $^
client:client.c comm.c
  gcc -o $@ $^
.PHONY:clean
clean:
  rm -f server client

结果



相关文章
|
10月前
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
算法
数据结构实验之操作系统打印机管理器问题
本实验旨在通过实现操作系统中的打印机管理器问题,掌握队列的基本操作如入队、出队等,利用队列的先进先出特性解决先申请先打印的问题。实验包括队列的初始化、入队、出队、打印队列内容等功能,并通过菜单式界面进行交互。实验结果显示基本功能可正常执行,但在连续操作时存在执行失败的情况,需进一步优化。
176 4
|
10月前
|
消息中间件 Linux C++
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
292 16
|
消息中间件 存储 供应链
进程间通信方式-----消息队列通信
【10月更文挑战第29天】消息队列通信是一种强大而灵活的进程间通信机制,它通过异步通信、解耦和缓冲等特性,为分布式系统和多进程应用提供了高效的通信方式。在实际应用中,需要根据具体的需求和场景,合理地选择和使用消息队列,以充分发挥其优势,同时注意其可能带来的复杂性和性能开销等问题。
|
存储 Unix Linux
进程间通信方式-----管道通信
【10月更文挑战第29天】管道通信是一种重要的进程间通信机制,它为进程间的数据传输和同步提供了一种简单有效的方法。通过合理地使用管道通信,可以实现不同进程之间的协作,提高系统的整体性能和效率。
|
存储 消息中间件 资源调度
「offer来了」进程线程有啥关系?10个知识点带你巩固操作系统基础知识
该文章总结了操作系统基础知识中的十个关键知识点,涵盖了进程与线程的概念及区别、进程间通信方式、线程同步机制、死锁现象及其预防方法、进程状态等内容,并通过具体实例帮助理解这些概念。
「offer来了」进程线程有啥关系?10个知识点带你巩固操作系统基础知识
|
算法 调度
探索操作系统的心脏:内核与进程管理
【10月更文挑战第25天】在数字世界的复杂迷宫中,操作系统扮演着关键角色,如同人体中的心脏,维持着整个系统的生命力。本文将深入浅出地剖析操作系统的核心组件——内核,以及它如何通过进程管理来协调资源的分配和使用。我们将从内核的概念出发,探讨它在操作系统中的地位和作用,进而深入了解进程管理的机制,包括进程调度、状态转换和同步。此外,文章还将展示一些简单的代码示例,帮助读者更好地理解这些抽象概念。让我们一起跟随这篇文章,揭开操作系统神秘的面纱,理解它如何支撑起我们日常的数字生活。
|
算法 调度 Python
探索操作系统的内核——一个简单的进程调度示例
【9月更文挑战第17天】在这篇文章中,我们将深入探讨操作系统的核心组件之一——进程调度。通过一个简化版的代码示例,我们将了解进程调度的基本概念、目的和实现方式。无论你是初学者还是有一定基础的学习者,这篇文章都将帮助你更好地理解操作系统中进程调度的原理和实践。
|
Java Android开发 数据安全/隐私保护
Android中多进程通信有几种方式?需要注意哪些问题?
本文介绍了Android中的多进程通信(IPC),探讨了IPC的重要性及其实现方式,如Intent、Binder、AIDL等,并通过一个使用Binder机制的示例详细说明了其实现过程。
933 4
|
调度 虚拟化 容器
探索操作系统的心脏:内核与进程管理
【8月更文挑战第28天】在数字世界的复杂迷宫中,操作系统扮演着关键角色。它如同一座桥梁,连接硬件与软件,确保一切顺畅运行。本文将深入剖析操作系统的核心——内核和进程管理,揭示它们如何协同工作,保障系统的稳定与高效。通过简化的比喻,我们将一探究竟,了解操作系统背后的神秘面纱。

热门文章

最新文章

推荐镜像

更多