知识点整理--Linux 通信机制

Linux进程通信机制

管道

信号量

消息队列

共享内存

Socket通信

Linux通信机制是指在Linux操作系统中实现进程间通信的方式和技术,主要包括以下几种通信机制:

1. 管道(Pipe):管道是一种半双工的通讯机制,它只能实现具有亲缘关系(如父子进程之间)的进程间通信。

2. 命名管道(FIFO):命名管道是一种特殊文件,可用于多个进程间通信。

3. 信号(Signal):信号是一种比较简单的通信机制,主要用于异步通信,进程间通信通过发送和接收信号来实现。

4. 消息队列(Message Queue):消息队列是一种进程间通信机制,它可以实现不同进程间的通信,通过消息发送和接收实现。

5. 共享内存(Shared Memory):共享内存是一种高效的通信机制,可以实现进程之间的数据共享,通过直接读写内存实现。

6. 信号量(Semaphore):信号量是一种进程间同步机制,可以用来保护共享资源,控制进程的访问。

7. 套接字(Socket):套接字是一种实现网络通信的机制,也可以实现进程间通信,通过网络协议实现进程间通信。

1.管道(先进新出)

实质:由内核管理的一个缓冲区

  • 信息输出,数据写入管道
  • 信息输入,从管道读取信息

匿名管道:亲缘关系  进程间通信  退出销毁

命名管道: 联系弱  读写内存接口 退出仍存在

匿名管道:

  • 创建 pipe()
  • 关闭不用端口,close()
  • 通信:读写操作,read/write()
  • 关闭,close()

    • 创建 pipe()

#include<unistd.h>

Int pipe(int pipefd[2]);//传入参数,文件描述符数组

父进程读,子进程写

pipe()创建管道后读端的文件描述符为fd[0]写端的文件描述符为fd[1]

dup2();

#include <unistd.h>

Int dup2(int oldfd,int newfd);

文件参数是要执行的可执行文件的路径名

【管道通信】:popen/pclose函数

#include <stdio.h>

FILE *popen(const char *command,const char *type);

Int pclose(FILE *stream);

Popen():

  • 调用pipe()à创建管道
  • 调用fork() à创建子进程
  • 子进程:通过execve()调用shell

Pclose()

    • 关闭popen()打开的I/O
    • 调用wait()等待子进程命令执行结束
    • 返回shell的终止状态,防止僵尸进程

2.命名管道

#include <sys/type.h>

#include <sys/stat.h>

Int mkfifo(const char *pathname,mode_t mode)

创建命名管道(FIFO文件) 文件形式存在  路径名->文件

FIFO文件和普通文件的区别:

Fifo 文件 对内存操作  读写  可以通过普通文件

普通文件 硬盘   读写慢

3.消息队列:管道改进版

本质:存放消息链表  内核 标识符:(队列key)

通信机制:传递的数据有结构  不是简单字节流

数据==数据结构(插入结点)

数据==数据结构(删除结点)

管道和消息队列的共同不足:每个数据块最大长度有限,系统上

全体队列的最大长度也有限

消息队列进程通信:

  • 创建消息队列
  • 发送消息->消息队列
  • 消息队列->读取
  • 删除消息队列

用户消息缓冲区

通过msgtype区分数据类型

Int msgget(key,IPC_CREAT|IPC_EXCL|0664);

表示:

若不存在,自动创建

若存在,返回(EEXIST),无需创建(创建并打开消息队列)

已存在,打开

如:

Int msgget(key,0664);

Msgget()://创建消息队列/获取已经存在的消息队列

#include <sys/msg.h>

Int mssget(key_t key ,int msgflg);

Msgsnd()://发送消息

#include <sys/msg.h>

Int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);

Msgrcv()://接收消息

#include <sys/msg.h>

Ssize_t msgcrv(int msqid, void *msgp,size_msgsz,long msgtyp,int msgflg);

Msgctl()://控制,删除,获取属性

#include <sys/ipc.h>

Int msg

Msgctl(int msqid,in cmd,struct msqid_ds *buf);

键值ID:msgget函数的返回值  >=0 内部名->进程级别的唯一标识

               不支持进程间通信

标识符(key):实现消息队列和进程的关联  外部名->内存级别的唯一标识

                       多个进程——>同一个key调用msgget ->标识同一个进程间通信的结构

4.信号量

作用:解决进程同步与互斥的通信机制

区别:不同于管道,FIFO,消息队列,不用来传输数据

包括:

资源数量:>=0变量

修改信号量:原子操作p,v

该信号下:等待资源的进程队列

步骤:

  • 创建信号量/集  获取已有的
  • 初始化信号量、信号量集
  • P,V操作:(1)修改信号量数量

                (2)P:-1

                  (3)V:+1

④删除不需要的信号量

Linux内核三个系统调用:

Semget()//创建新的信号量、集  获取已经存在的

#include <sys/sem.h>

Int semget(key_t key键值,传入参数),int nsems信号量数目),int semflg(设置权限));

Semctl()//信号量控制  (初始化,删除)

#include <sys/sem.h>

Int semctl(int semid(信号量标识符,semgget返回值),int semnum(编号),int cmd(SETVAL—初始化,IPC-RMID-删除)

Semop()//改变信号量的值

#include <sys/sem.h>

Int semop(int semid(信号量标识符),struct sembuf *sops(struct sembuf 的数组指针),unsigned nsops(sops所指的元素个数));

共享内存(效率最高)

允许>=2的进程访问同一个存储区域、

共享内存与信号量一起,信号量:读写操作同步

  • 获得一块共享内存段
  • 创建的共享内存段->映射->不同进程空间(可断开)
  • 不需要访问时,断开映射
  • 不需要时,释放共享内存段

Linux系统调用:

Shmget()//创建共享内存段,打开已有的

#include <sys/shm.h>

Int shmget(key_t  key(传入参数,键值),size_t size共享内存大小),int shmflg(shmget创建条件,权限));

Shmat()//地址映射

#include <sys/shm.h>

Void shmat(int shmid(共享内存标识,shmget返回值),const void *shmaddr(指针类型的传入参数,映射地址),int shmflg(使用方式));

Shmdt()//解除物理内存进程虚拟地址空间的映射关系

#include <sys/shm.h>

Int shmdt(const void *shmaddr(shmat返回的虚拟空间地址));

Shmctl()//已存在的操作

#include <sys/shm.h>

Int shmctl(int shmid(共享内存标识符),int cmdS(IPC-STAT 属性保存在3  IPC-SET  用3设置属性   IPC-RMID 删除  3为null),struct shmid_ds *buf(shmid-ds 的指针));

特殊说明

共享内存,消息队列,信号量     释放

调用fork()创建子进程,继承父进程联系的共享内存

调用exec()函数更改时,exit函数时,      子进程解除映射        shmctl进行删除

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值