Linux —— 进程间通信(System V)

news2024/12/28 18:20:59

目录

一,共享内存

申请共享内存 shmget

控制共享内存 shmctl

关联共享内存 shmat / 去联共享内存 shmdt

二,消息队列

创建或打开消息队列 msgget

发送消息 msgsnd / 接收消息 msgrcv

控制消息 msgctl

三,信号量

创建或打开信号量 semget

信号量操作 semop

信号量控制 semctl


一,共享内存

        共享内存是最快的进程间通信IPC形式,即允许两个或多个进程共享物理内存的同一块区域(通常被称为段),进程间数据传递将不再涉及到内核(即将不再通过内核系统调用来传递数据);

维护共享内存的数据结构

//vim /usr/include/bits/shm.h
struct shmid_ds {
    struct ipc_perm shm_perm; /* operation perms */
    int shm_segsz; /* size of segment (bytes) */
    __kernel_time_t shm_atime; /* last attach time */
    __kernel_time_t shm_dtime; /* last detach time */
    __kernel_time_t shm_ctime; /* last change time */
    __kernel_ipc_pid_t shm_cpid; /* pid of creator */
    __kernel_ipc_pid_t shm_lpid; /* pid of last operator */
    unsigned short shm_nattch; /* no. of current attaches */
    unsigned short shm_unused; /* compatibility */
    void *shm_unused2; /* ditto - used by DIPC */
    void *shm_unused3; /* unused */
};
//vim /usr/include/bits/ipc.h
 /* Data structure used to pass permission information to IPC operations.  */    
  struct ipc_perm    
    {    
      __key_t __key;      /* Key.  */    
      __uid_t uid;      /* Owner's user ID.  */    
      __gid_t gid;      /* Owner's group ID.  */    
      __uid_t cuid;     /* Creator's user ID.  */    
      __gid_t cgid;     /* Creator's group ID.  */    
      unsigned short int mode;    /* Read/write permission.  */    
      unsigned short int __pad1;    
      unsigned short int __seq;   /* Sequence number.  */    
      unsigned short int __pad2;    
      __syscall_ulong_t __unused1;    
      __syscall_ulong_t __unused2;    
    }; 

申请共享内存 shmget

  • key,用于唯一区分共享内存,可由ftok函数生成;
  • size,建议为4KB的倍数;
  • shmflg,标签;
    • IPC_CREAT,如目标共享内存不存在,即创建,否则获取;
    • IPC_CREAT | IPC_EXCL,如目标共享内存不存在,即创建,否则出错;

//vim /usr/include/bits/ipc.h
  #include <bits/types.h>    
      
  /* Mode bits for `msgget', `semget', and `shmget'.  */    
  #define IPC_CREAT 01000   /* Create key if key does not exist. */    
  #define IPC_EXCL  02000   /* Fail if key exists.  */    
  #define IPC_NOWAIT  04000   /* Return error on wait.  */    
      
  /* Control commands for `msgctl', `semctl', and `shmctl'.  */    
  #define IPC_RMID  0   /* Remove identifier.  */    
  #define IPC_SET   1   /* Set `ipc_perm' options.  */    
  #define IPC_STAT  2   /* Get `ipc_perm' options.  */    
  #ifdef __USE_GNU    
  # define IPC_INFO 3   /* See ipcs.  */    
  #endif 

控制共享内存 shmctl

关联共享内存 shmat / 去联共享内存 shmdt

//makefile
CC=gcc    
.PHONY:all    
all: server client    
    
server:server.c    
  $(CC) -o $@ $^        
client:client.c    
  $(CC) -o $@ $^        
        
.PHONY:clean        
clean:    
  rm -rf server client  
//comm.h
#pragma once    
#include <stdio.h>    
    
#define PATH_NAME "/home/wz/Desktop/pipe"    
#define PROJ_ID 0x6666

#define SIZE 4097
//server.c
include "comm.h"    
#include <stdio.h>    
#include <unistd.h>    
#include <string.h>    
#include <sys/types.h>    
#include <sys/ipc.h>    
#include <sys/shm.h>    
    
int main()    
{    
  key_t k = ftok(PATH_NAME, PROJ_ID);    
  if(k < 0){    
    perror("ftok");    
    return 1;    
  }    
  printf("key: %x\n", k);    
  sleep(3);    
    
  int shmid = shmget(k, SIZE, IPC_CREAT|IPC_EXCL|0644);    
  if(shmid < 0){    
    perror("shmget");    
    return 2;    
  }    
  printf("shmid: %d\n", shmid);    
  sleep(3);    
    
  char* start = (char*)shmat(shmid, NULL, 0);    
  printf("server already attach on shared memory!\n");    
  while(1){    
    printf("%s\n", start);    
    sleep(1);                                                                                                  
    if(strlen(start) == 26)    
      break;    
  }    
    
  shmdt(start);    
  printf("server already dattach off shared memory!\n");    
  sleep(3);    
    
  shmctl(shmid, IPC_RMID, NULL);    
  printf("delete %d\n", shmid);    
  return 0;    
}  
//client.c
#include "comm.h"    
#include <stdio.h>    
#include <unistd.h>    
#include <string.h>    
#include <sys/types.h>    
#include <sys/ipc.h>    
#include <sys/shm.h>    
    
int main()    
{    
  key_t k = ftok(PATH_NAME, PROJ_ID);    
  if(k < 0){    
    perror("ftok");    
    return 1;    
  }    
  printf("key: %x\n", k);    
  sleep(3);    
    
  int shmid = shmget(k, SIZE, IPC_CREAT);    
  if(shmid < 0){    
    perror("shmget");    
    return 2;    
  }    
  printf("client shmid: %d\n", shmid);    
  sleep(3);    
    
  char* start = (char*)shmat(shmid, NULL, 0);    
  printf("client already attach on shared memory!\n");    
    
  char c = 'A';    
  while(c <= 'Z'){    
    start[c - 'A'] = c;    
    c++;    
    sleep(1);                                                                                                  
  }    
    
  shmdt(start);    
  printf("client already dattach off shared memory!\n");    
  sleep(3);    
  return 0;    
}    
//查看共享内存
[wz@192 pipe]$ ipcs -m
//删除指定id共享内存
[wz@192 pipe]$ ipcrm -m 426047

共享内存的生命周期随OS;

共享内存不提供任何同步与互斥,彼此独立;

共享内存是所有进程间通信中,速度最快的;

共享内存系统分配的shm,是按照4KB为基本单位的,如指定不是4KB的倍数,多余会浪费掉;

二,消息队列

        消息队列是进程间通信的一种方式,提供一个从一个进程向另一个进程发生一块数据的方法;

维护消息队列的数据结构

//vim /usr/include/bits/msq.h 
/* Structure of record for one message inside the kernel.    
     The type `struct msg' is opaque.  */    
  struct msqid_ds    
  {    
E>  struct ipc_perm msg_perm; /* structure describing operation permission */    
    __time_t msg_stime;   /* time of last msgsnd command */    
  #ifndef __x86_64__    
    unsigned long int __unused1;    
  #endif    
    __time_t msg_rtime;   /* time of last msgrcv command */    
  #ifndef __x86_64__    
    unsigned long int __unused2;    
  #endif    
    __time_t msg_ctime;   /* time of last change */                                                            
  #ifndef __x86_64__    
    unsigned long int __unused3;    
  #endif    
    __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */    
    msgqnum_t msg_qnum;   /* number of messages currently on queue */    
    msglen_t msg_qbytes;    /* max number of bytes allowed on queue */    
    __pid_t msg_lspid;    /* pid of last msgsnd() */    
    __pid_t msg_lrpid;    /* pid of last msgrcv() */    
    __syscall_ulong_t __unused4;    
    __syscall_ulong_t __unused5;    
  }; 

创建或打开消息队列 msgget

  • key,用于唯一区分共享内存,可由ftok函数生成;
  • msgflg,标签;
    • IPC_CREAT,如目标消息队列不存在,即创建,否则获取;
    • IPC_CREAT | IPC_EXCL,如目标消息队列不存在,即创建,否则出错;

发送消息 msgsnd / 接收消息 msgrcv

控制消息 msgctl

三,信号量

        信号量并不是原来进程间传输数据的,是原来同步进程当作的,主要用于同步与互斥;由于进程要求共享资源,而有些资源需互斥使用;系统中的某些资源一次只允许一个进程使用,称这些资源为临界资源或互斥资源;涉及到互斥资源的程序段,称为临界区;

维护信号量的数据结构

//vim /usr/include/bits/sem.h 
  /* Data structure describing a set of semaphores.  */    
  struct semid_ds    
  {    
    struct ipc_perm sem_perm;   /* operation permission struct */    
    __time_t sem_otime;     /* last semop() time */    
    __syscall_ulong_t __unused1;    
    __time_t sem_ctime;     /* last time changed by semctl() */    
    __syscall_ulong_t __unused2;    
    __syscall_ulong_t sem_nsems;    /* number of semaphores in set */    
    __syscall_ulong_t __unused3;    
    __syscall_ulong_t __unused4;    
  };    

创建或打开信号量 semget

信号量操作 semop

信号量控制 semctl

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/902551.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java八股文面试[java基础]——面相对象特点

三大特点&#xff1a; 封装 继承 多态 面试题&#xff1a;java如何实现多继承&#xff08;除了使用接口之外&#xff09; 实现多继承有三个方法&#xff1a; 多层继承内部类接口 知识来源&#xff1a; 【基础】面向对象_哔哩哔哩_bilibili 【2023年面试】Java面向对象有哪些…

Vue--BM记事本

效果如下&#xff1a; 用到了如下的技术&#xff1a; 1.列表渲染&#xff1a;v-for key的设置 2.删除功能&#xff1a;v-on调用参数 fliter过滤 覆盖修改原数组 3.添加功能&#xff1a;v-model绑定&#xff0c;unshift修改原数组添加 html文件如下&#xff1a; <!DOCTYPE …

1.进程控制

1.进程概念 进程是管理事务的基本单元 2.并发并行 并行(parallel)&#xff1a;指在同一时刻&#xff0c;有多条指令在多个处理器上同时执行。并发(concurrency)&#xff1a;指在同一时刻只能有一条指令执行&#xff0c;但多个进程指令被快速的轮换执行&#xff0c;使得在宏观上…

7-5 特殊a串数列求和

分数 20 全屏浏览题目 切换布局 作者 颜晖 单位 浙大城市学院 给定两个均不超过9的正整数a和n&#xff0c;要求编写程序求aaaaaa⋯aa⋯a&#xff08;n个a&#xff09;之和。 输入格式&#xff1a; 输入在一行中给出不超过9的正整数a和n。 输出格式&#xff1a; 在一行中…

回归预测 | MATLAB实现NGO-SVM北方苍鹰算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现NGO-SVM北方苍鹰算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现NGO-SVM北方苍鹰算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基…

华为网络篇 多区域OSPF-32

难度2复杂度2 目录 一、实验原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 OSPF是一种具有区域概念的路由协议&#xff0c;为什么需要分区域&#xff1f;像RIP那样都在一个区域配置也不多这样简单点不是更好吗&#xff1f;OSPF它是一种功能十分强大的IG…

基于Java+SpringBoot+Vue的学校田径运动会管理系统【源码+论文+演示视频+包运行成功】

博主介绍&#xff1a;✌擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案…

本地事务和分布式事务

参考连接分布式事务有这一篇就够了&#xff01; - 知乎 (zhihu.com) 本地事务 使用服务自己的数据库来控制事务&#xff0c;我们常使用的transaction注解。transaction注解是基于spring基于aop思想利用数据库的事务来进行事务控制。 begin transaction&#xff1b;//1.本地数…

go语言中channel类型

目录 什么是channel 为什么要有channel channel操作使用 初始化&#xff1a; 操作&#xff1a; 单向channel 双向channel&#xff0c;可读可写&#xff1a; close下什么场景会出现panic 总结 什么是channel Channels are a typed conduit through which you can send …

RabbitMQ介绍及常见消息队列

1. RabbitMQ 1.1. 搜索与商品服务的问题 假设我们已经完成了商品详情和搜索系统的开发。我们思考一下&#xff0c;是否存在问题&#xff1f; o 商品的原始数据保存在数据库中&#xff0c;增删改查都在数据库中完成。 o 搜索服务数据来源是索引库&#xff0c;如果数据库商品发…

QT C++实现简易便签

总想着下载一个便签出来自己用&#xff0c;但网上下载的不是功能太多&#xff0c;好多功能都用不到&#xff0c;就是功能太少了&#xff0c;或是界面不太符合自己审美。所以干脆想着自己做一个算了&#xff0c;反正也不是很麻烦。 需求功能&#xff1a; 开机自启动&#xff0c…

无涯教程-PHP - 循环语句

PHP中的循环用于执行相同的代码块指定的次数。 PHP支持以下四种循环类型。 for - 在代码块中循环指定的次数。 while - 如果且只要指定条件为真&#xff0c;就会循环遍历代码块。 do ... while - 循环执行一次代码块&#xf…

Over Permision

文章目录 水平越权垂直越权 如果使用A用户的权限去操作B用户的数据&#xff0c;A的权限小于B的权限&#xff0c;如果能够成功操作&#xff0c;则称之为越权操作。 越权漏洞形成的原因是后台使用了 不合理的权限校验规则导致的。 一般越权漏洞容易出现在权限页面&#xff08;需…

什么是cURL?

cURL无处不在。它几乎隐藏在所有设备中&#xff0c;例如汽车&#xff0c;蓝光播放器等。它通过互联网协议传输任意类型数据。 在本文中&#xff0c;我们将揭开cURL神秘命令行工具的面纱&#xff0c;解释它是如何成为一种通用代码的&#xff0c;并举例说明其用法。 cURL是什么意…

[MAUI]模仿网易云音乐黑胶唱片的交互实现

用过网易云音乐App的同学应该都比较熟悉它播放界面。 这是一个良好的交互设计&#xff0c;留声机的界面隐喻准确地向人们传达产品概念和使用方法&#xff1a;当手指左右滑动时&#xff0c;便模拟了更换唱盘从而导向切换歌曲的交互功能。 今天在 .NET MAUI 中我们来实现这个交互…

地球IT

地球是我们生活的家园&#xff0c;也是人类发展的基地。地球不仅仅是一个行星&#xff0c;更是一个复杂而有机的生态系统。 地球直径约为12,742公里&#xff0c;被称为“蓝色星球”&#xff0c;因为它的表面约70%被水覆盖。海洋是地球上最大的生态系统之一&#xff0c;它们扮演…

商城-学习整理-高级-商城业务-异步线程池(十三)

目录 一、线程1、初始化线程的 4 种方式2、线程池的七大参数3、线程池的运行流程&#xff1a;4、例子5、常见的 4 种线程池6、开发中为什么使用线程池 二、CompletableFuture 异步编排0、业务场景&#xff1a;1、创建异步对象2、计算完成时回调方法3、handle 方法4、线程串行化…

springboot 项目日志配置文件详解

spring boot 项目指定 日志配置文件 在Spring Boot项目中&#xff0c;可以通过在application.properties或application.yml文件中指定日志配置文件来配置日志。 1. 使用application.properties文件&#xff1a; 在application.properties中&#xff0c;您可以使用以下属性来…

系统卡死问题分析

CPU模式 CPU Frequency Scaling (CPUFREQ) Introduction CPU频率调节设备驱动程序的功能。该驱动程序允许在运行过程中更改CPU的时钟频率。一旦CPU频率被更改,必要的电源供应电压也会根据设备树脚本(DTS)中定义的电压值进行变化。通过降低时钟速度,这种方法可以减少功耗…

C语言刷题训练DAY.9

1.线段图案 解题思路&#xff1a; 这里非常简单&#xff0c;我们只需要用一个循环控制打印即可。 解题代码&#xff1a; #include<stdio.h> int main() {int n 0;while ((scanf("%d", &n)) ! EOF){int i 0;for (i 0; i < n; i){printf("*&…