Linux--信号量共享内存

news2025/7/13 5:11:44

1.基础知识:

(1)共享内存是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间的数据传递不再涉及内核,即进程不再通过执行进入内核的系统调用来传递彼此的数据。

(2)共享内存的生命周期随内核。

(3)注意:共享内存未提供任何保护资源,即共享内存自身没有同步与互斥机制,但它是临界资源,所以我们需要利用其它机制来保证数据的正确性,Linux下就可以用信号量达到同步的目的。

(4)linux共享内存有两种方式(本文主要介绍shmget方式):

                1)mmap方式,适用于父子进程之间,创建的内存非常大时;

                2)shmget方式,适用于同一台电脑上不同进程之间,创建的内存相对较小。

(5)进程间利用共享内存实现消息队列的基本原理如下图

 2.相关函数

1.semget

 

1.函数原型

2.函数功能

创建或者获取一个已经存在的信号量;

如果为全新创建,也就是不知道是否有人创建过,IPC_CREATE|IPC_EXCEL,就是如果没

有则创建 , 如果有则创建失败 ;

3.参数

key:两个进程使用相同的key,就可以使用同一个信号量;

nsems:创建几个信号量;

semflg:标志位;如果为创建:IPC_CREAT;

4.返回值

成功返回一个非负整数即该信号集的标识码;失败返回-1

2.semop

1.函数原型

2.函数功能

对信号量进行改变,P操作或者V操作;

3.参数

semid:信号量的id,也就是刚才semget的返回值;说明对哪个信号量进行操作;

sops:结构体指针,指向sembuf的结构体指针,sembuf结构体有三个成员变量:sem_num

示信号量的编号 ( 即指定信号量集中的信号量下标 );

nsops:表示是p还是v操作;1v操作 (1),-1p操作(1);sem_flg为标志位;

4.返回值

成功返回0;失败返回-1

5.说明

unsigned short sem_num;  /* semaphore number */第几个信号量
short          sem_op;   /* semaphore operation */p(-1)操作还是v操作(+1)
short          sem_flg;  /* operation flags */标志位

3.semctl

1.函数原型

**注意**:联合体semun,这个联合体需要自己定义; 

2.函数功能

控制信号量集 对信号量进行控制:初始化/删除信号量

3.参数

semid:信号量id;  由semget函数返回的信号量集标识码

semnum:信号量编号信号量集中信号量的序号

cmd:命令:SETVAL:初始化信号量; IPC_RMID:删除信号量将要采取的动作(有三个可取值)

4.返回值

成功返回0,失败返回-1

3.思路:

 

4.代码

1. sem.h

#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/sem.h>

union semun
{
    int val;
};

void sem_init();
void sem_p(int index);
void sem_v(int index);
void sem_destroy();

2.sem.c

#include "sem.h"
#define  SEM_NUM  2
static int semid = -1;
void sem_init()
{
    semid = semget((key_t)1234,SEM_NUM,IPC_CREAT|IPC_EXCL|0600);//全新创建
    if (semid == -1 )
    {
        semid = semget((key_t)1234,SEM_NUM,0600);
        if ( semid == -1)
        {
            printf("semget err\n");
            return;
        }
    }
    else
    {
        int arr[SEM_NUM] = {1,0};
        for( int i = 0; i < SEM_NUM; i++ )
        {
            union semun a;
            a.val = arr[i];
            if ( semctl(semid,i,SETVAL,a) == -1 )//全新创建成功,就初始化
            {
                printf("semctl err\n");
            }
        }
    }
}
void sem_p(int index)
{
    if ( index < 0 || index >= SEM_NUM )
    {
        return;
    }
    struct sembuf buf;
    buf.sem_num = index;
    buf.sem_op = -1;//p
    buf.sem_flg = SEM_UNDO;
    if ( semop(semid,&buf,1) == -1 )
    {
        printf("sem p err\n");
    }
}
void sem_v(int index)
{
    if ( index < 0 || index >= SEM_NUM )
    {
        return;
    }
    struct sembuf buf;
    buf.sem_num = index;
    buf.sem_op = 1;//v
    buf.sem_flg = SEM_UNDO;
    if ( semop(semid,&buf,1) == -1 )
    {
        printf("sem v err\n");
    }
}
void sem_destroy()
{
    if ( semctl(semid,0,IPC_RMID) == -1 )
    {
        printf("semctl del err\n");
    }
}

3.a.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
#include "sem.h"
int main()
{
    int  shmid = shmget((key_t)1234,256,0600|IPC_CREAT);//创建/获取共享内存
    if ( shmid == -1 )
    {
        printf("shmget err\n");
        exit(0);
    }

    char* s = (char*)shmat(shmid,NULL,0);
    if ( s == (char*)-1 )
    {
        printf("shmat err\n");
        exit(0);
    }

    sem_init();//2  1,0
    while( 1 )
    {
        printf("input\n");
        char buff[128] = {0};
        fgets(buff,128,stdin);
        sem_p(0);
        strcpy(s,buff);
        sem_v(1);
        if ( strncmp(buff,"end",3) == 0 )
        {
            break;
        }
    }

    shmdt(s);
    exit(0);
}

4.b.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
#include "sem.h"
int main()
{
    int  shmid = shmget((key_t)1234,256,0600|IPC_CREAT);//创建/获取共享内存
    if ( shmid == -1 )
    {
        printf("shmget err\n");
        exit(0);
    }

    char* s = (char*)shmat(shmid,NULL,0);
    if ( s == (char*)-1 )
    {
        printf("shmat err\n");
        exit(0);
    }

    sem_init();//2  1,0
    while( 1 )
    {
        printf("input\n");
        char buff[128] = {0};
        fgets(buff,128,stdin);
        sem_p(0);
        strcpy(s,buff);
        sem_v(1);
        if ( strncmp(buff,"end",3) == 0 )
        {
            break;
        }
    }

    shmdt(s);
    exit(0);
}

 

 只运行b.c,会阻塞

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

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

相关文章

MySQL浅析之架构概览

MySQL主要分为Server层&#xff0c;跟存储引擎层。 Server层负责“逻辑处理”&#xff0c;包括连接器、分析器、优化器、执行器以及所有内置函数。所有跨存储引擎的功能都在这一层实现&#xff0c;比如存储过程、触发器、视图等。 存储引擎层跟文件系统交互&#xff0c;负责数…

bug探索之路:List<Map>get取出元素却是String?

一、bug初现峥嵘 有一说一我定义的List<Map>对吧&#xff0c;我get(0)取出的元素也应该是Map类型没问题吧。不行&#xff0c;编译器告诉我&#xff0c;java.lang.String cannot be cast to java.util.Map。 这个意思就是说&#xff0c;你这个就是String类型&#xff0c;…

Spring Cloud Gateway夺命连环10问?

这篇文章介绍下微服务中的一个重要角色&#xff1a;网关&#xff0c;对于网关如何选择&#xff0c;由于阿里系暂时未出网关&#xff0c;当然是选择了Spring cloud Gateway&#xff0c;毕竟是亲儿子。 文章目录如下&#xff1a; ​ 编辑切换为居中 添加图片注释&#xff0c;不…

[附源码]java毕业设计智能超市导购系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【科学文献计量】RC.networkBibCoupling()中的参数解释

RC.networkBibCoupling中的参数解释 1 数据2 RC.networkBibCoupling()中的参数解释2.1 测试weighted参数2.2 测试fullInfo参数2.3 测试addCR参数1 数据 使用web of science中的数据,借助metaknowledge库读入到python中,然后截取2020-2021年的数据构建网络 2 RC.networkBib…

CrystalNet ADO.Net VCL for Delphi

CrystalNet ADO.Net VCL for Delphi ADO。用于Delphi的Net DAC被描述为数据库的最快和最可靠的连接&#xff0c;以及使用ADO技术的虚拟和数据库的替代方案。NET在Delphi。它能够为用户和开发人员提供对信息源的数据访问&#xff0c;这些信息源不喜欢SQL Server、Oracle、Vista…

Flutter高仿微信-第42篇-创建群

Flutter高仿微信系列共59篇&#xff0c;从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。 详情请查看 效果图&#xff1a; 实现代码&#xff1a; /*** Author : wangning* Email : maoning20080809163.c…

ARM S5PV210的启动过程

一、内存 SRAM 静态内存 特点就是容量小、价格高&#xff0c;优点是不需要软件初始化直接上电就能用。DRAM 动态内存 特点就是容量大、价格低&#xff0c;缺点就是上电后不能直接使用&#xff0c;需要软件初始化后才可以使用。 单片机中&#xff1a;内存需求量小&#xff0c;而…

秉持技术普惠的华为,致力于无处不在的联接

编辑 | 阿冒 设计 | 沐由经济学家托马斯弗里德曼在《世界是平的》一书中曾经指出&#xff1a;“科技和通信领域如闪电般迅速的进步&#xff0c;使全世界的人们可以空前地彼此接近。”然而&#xff0c;在世界各国和地区的政府工作报告中&#xff0c;“数字鸿沟”一词出现的频…

致敬最美逆行者网页设计作品 大学生抗疫感动专题网页设计作业模板 疫情感动人物静态HTML网页模板下载

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

【Matlab代码】基于遗传算法和蚂蚁优化算法的路径优化问题

目录 1 概述 2 Matlab代码 3 运行结果 1 概述 在1959年&#xff0c;Dantzing 和 Ramser在经过实验和思考后&#xff0c;首次提出配送车辆路径优化问题。在物流运输中配送是重要的环节&#xff0c;准确选择配送车辆路径能有效缩短运输时间、降低运输成本、满足顾客需求等目的…

C语言 * 数组的解析 *

目录 一&#xff1a;一维数组的创建和初始化 1.1 数组的创建 1.2 数组的初始化 1.3 一维数组的使用 1.4 一维数组在内存中的存储 二&#xff1a;二维数组的创建和初始化 2.1 数组的创建 2.2 数组的初始化 2.3 一维数组的使用 2.4 一维数组在内存中的存储 2.5 数组越…

黑苹果系统安装常见问题汇集

常见问题 黑苹果折腾之路上遇到的问题多种多样&#xff0c;这里把常见问题分为安装篇、使用篇、进阶篇。 安装篇 如何安装黑苹果&#xff1f; 目前主要有两种方式&#xff0c;第一种是推荐的方式&#xff1a;下载黑苹果安装镜像 → 刻录到U盘 → 调整配置文件 → 格式化准备…

又一款机器学习模型解释神器:LIME

在机器学习的许多应用中&#xff0c;要求用户信任模型来帮助他们做出决策。医生肯定不会仅仅因为“模型这么说”就给病人做手术。即使在风险较低的情况下&#xff0c;例如从 Netflix 选择要观看的电影时&#xff0c;在我们根据模型放弃几个小时的时间之前&#xff0c;也需要一定…

红黑树封装 map/set 及其迭代器(C++)

目录 一、map/set 的封装 1.1 封装思路 1.2 红黑树节点调整 1.3 map 和 set 的定义 1.4 仿函数 KeyOfValue 1.5 map/set 的插入 二、map/set 迭代器实现 2.1 迭代器的定义 2.2 解引用运算符重载 2.3 成员访问运算符重载 2.4 (不)等于运算符重载 2.5 begin() 与 end…

[附源码]java毕业设计智慧农业销售平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

认知电子战 | 电子战简介

1 电子战的基本概念 电子战(Electronic Warfare,EW)也叫做电子对抗(Electronic Counter Measures,ECM) 简洁定义: 电子战是为确保我方使用电磁频谱,同时阻止敌方使用电磁频谱所采取的战术与技术 完善定义: 利用电磁能、定向能、水声能等的技术手段,确定、扰乱、削弱…

Linux kprobe原理

文章目录前言一、Kprobes and Return Probes二、How Does a Kprobe Work三、Changing Execution Path四、Return Probes4.1 How Does a Return Probe Work4.2 Kretprobe entry-handler五、How Does Jump Optimization Work5.1 Init a Kprobe5.2 Safety Check5.3 Preparing Deto…

Ubuntu配置全局系统代理(常用工具配置)

Ubuntu配置全局系统代理&#xff08;常用工具&#xff09;问题描述解决方法配置系统代理终端部分配置配置apt代理配置curl,wget,pip代理git相关代理的设置配置docker代理问题描述 公司电脑网络规则做了限制&#xff0c;主机没办法通外网&#xff0c;只能通过代理连接外网。主机…

普惠联接,让人类诗意地栖居在大地上

弗里德里希荷尔德林为世间留下了一句精彩绝伦的诗句&#xff1a;“人生在世&#xff0c;成绩斐然&#xff0c;却还依然诗意地栖居在大地上。”“人&#xff0c;诗意地栖居”&#xff0c;这一命题启发了此后众多思想家、社会学家的缪斯。人之为人&#xff0c;应该如何成为存在的…