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

这篇具有很好参考价值的文章主要介绍了Linux —— 进程间通信(System V)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一,共享内存

申请共享内存 shmget

控制共享内存 shmctl

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

二,消息队列

创建或打开消息队列 msgget

发送消息 msgsnd / 接收消息 msgrcv

控制消息 msgctl

三,信号量

创建或打开信号量 semget

信号量操作 semop

信号量控制 semctl


一,共享内存

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

Linux —— 进程间通信(System V),操作系统,linux

维护共享内存的数据结构

//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,如目标共享内存不存在,即创建,否则出错;

Linux —— 进程间通信(System V),操作系统,linux

//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

Linux —— 进程间通信(System V),操作系统,linux

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

Linux —— 进程间通信(System V),操作系统,linux

//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,如目标消息队列不存在,即创建,否则出错;

Linux —— 进程间通信(System V),操作系统,linux

发送消息 msgsnd / 接收消息 msgrcv

Linux —— 进程间通信(System V),操作系统,linux

控制消息 msgctl

Linux —— 进程间通信(System V),操作系统,linux

三,信号量

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

维护信号量的数据结构

//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

Linux —— 进程间通信(System V),操作系统,linux

信号量操作 semop

Linux —— 进程间通信(System V),操作系统,linux

信号量控制 semctl

Linux —— 进程间通信(System V),操作系统,linux

 文章来源地址https://www.toymoban.com/news/detail-662515.html

到了这里,关于Linux —— 进程间通信(System V)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 操作系统课程设计-Linux 进程控制

    目录 前言 1 实验题目 2 实验目的 3 实验内容 3.1 进程的创建 3.1.1 步骤 3.1.2 关键代码 3.2 子进程执行新任务 3.2.1 步骤 3.2.2 关键代码 4 实验结果与分析 4.1 进程的创建 4.2 子进程执行新任务 5 代码 5.1 进程的创建 5.2 子进程执行新任务          本实验为课设内容,博客内容为

    2024年01月18日
    浏览(43)
  • 【Linux】操作系统与进程的概念

    目录 冯诺依曼体系 注意 为什么CPU不直接访问输入或输出设备? 跨主机间数据的传递 操作系统 管理 进程 描述进程 进程的查看和终止  bash 通过系统调用创建子进程 fork的辨析 🥖冯·诺依曼结构也称普林斯顿结构,是一种 将程序指令存储器和数据存储器合并在一起的存储器

    2024年01月18日
    浏览(34)
  • Linux操作系统——第五章 进程信号

          目录 信号概念 用kill -l命令可以察看系统定义的信号列表 信号处理常见方式概览 产生信号 1. 通过终端按键产生信号 2. 调用系统函数向进程发信号 3. 由软件条件产生信号 4. 硬件异常产生信号 阻塞信号 1. 信号其他相关常见概念 2. 在内核中的表示 3. sigset_t 4. 信号集操作

    2024年02月11日
    浏览(33)
  • 【Linux操作系统】深入探索Linux进程:创建、共享与管理

    进程的创建是Linux系统编程中的重要概念之一。在本节中,我们将介绍进程的创建、获取进程ID和父进程ID、进程共享、exec函数族、wait和waitpid等相关内容。 在Linux系统中,进程的创建使用 fork() 系统调用。 fork() 系统调用会创建一个与当前进程相同的子进程,子进程会复制父进

    2024年02月12日
    浏览(40)
  • Linux操作系统-06-进程与服务管理

    使用ps命令查看进程。包括过滤进程信息 使用systemctl命令管理和运行Linux服务 进程(Process):操作系统正在运行的应用程序。任意一个进程,都会消耗CPU和内存资源, 服务(Service):通过服务控制面板直接启动的应用程序,也可能是操作系统启动时自启动的后台应用程序。

    2024年03月12日
    浏览(40)
  • Linux操作系统——第二章 进程控制

        目录 进程创建 fork函数初识 fork函数返回值 写时拷贝 fork常规用法 fork调用失败的原因 进程终止 进程退出场景 进程常见退出方法 _exit函数 exit函数 return退出 进程等待 进程等待必要性 进程等待的方法 wait方法 waitpid方法 获取子进程status 进程程序替换 替换原理 替换函数

    2024年02月08日
    浏览(34)
  • 【Linux】初步理解操作系统和进程概念

    操作系统是一款纯正的 “搞管理” 的文件 。 那操作系统为什么要管理文件? “管理” 又是什么? 它是怎么管理的? 1.操作系统帮助用户,管理好底层的软硬件资源; 2.为了给用户提供一个良好,安全的环境 即操作系统通过管理好底层的软硬件资源,为用户提供一个良好

    2024年02月15日
    浏览(27)
  • 【Linux】进程概念(冯诺依曼体系结构、操作系统、进程)-- 详解

    1、概念 (1)什么是冯诺伊曼体系结构? 数学家冯·诺伊曼于 1946 年提出存储程序原理,把程序本身当作数据来对待,程序和该程序处理的数据用同样的方式储存。 冯·诺伊曼理论的要点是:计算机的数制采用二进制逻辑;计算机应该按照程序顺序执行。人们把冯·诺伊曼的

    2024年02月22日
    浏览(40)
  • 操作系统练习:在Linux上创建进程,及查看进程状态

    进程在执行过程中可以创建多个新的进程。创建进程称为“父进程”,新的进程称为“子进程”。每个新的进程可以再创建其他进程,从而形成进程树。 每个进程都有一个唯一的进程标识符(process identifier,pid)。在Linux中,init进程是所有其他进程的根进程。 在Linux中,可以

    2024年02月12日
    浏览(39)
  • 麒麟操作系统(Linux)使用和维护:进程相关的操作命令

      目录 1. 查看进程 2. top命令实时监控进程 3. 杀死进程 4. 图形界面查看和杀死进程         作为国产操作系统,无论是银河麒麟,还是中标麒麟,它们的服务器操作系统或者桌面操作系统,已经广泛应用于工业生产和科学研究领域。因为麒麟操作系统的内核是Linux系统内

    2024年02月04日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包