Linux 之 System V信号量

2023-05-16

其实就是学几个函数的用法:ftok(),  semget() , semctl(),  semop()   如果对哪个函数不熟悉就man 一下,例如man semctl()

下面是几个函数简单的实现代码,自己可以实现一下,助于理解...

sem.h:

对相应的系统函数”包装“,便于使用,例如
Ftok()对应于系统里的ftok();

//sem.h

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

key_t Ftok(const char *pathname, int proj_id)
{
    key_t key = ftok(pathname, proj_id);
    if(key == -1)
      {
          perror("ftok Error.\n");
          exit(1);
      }

    return key;
}


int Semget(key_t key, int nsems, int semflg)
{
    int sem_id = semget(key, nsems, semflg);
    if(sem_id == -1)
    {
       perror("sem_get Error.\n");
       exit(1);
    }

    return sem_id;
}

union semun 
{
   int               val;
   struct semid_ds  *buf;
   unsigned short   *array;
   struct seminfo   *__buf;
};

创建信号量:Ftok()、Semget()

这里的创建呢,信号量就相当于一个数组,然后,你创建多少个n个信号量,就把这个大的数组分成n个,下标从0到n-1,依次标识。到时候你操作哪个就写哪个下标即可。

//sem_create.c

#include"sem.h"

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
      printf("<Warning Usage>: %s pathname proj_id.\n",argv[0]);
      return -1;
    }

    key_t sem_key = Ftok(argv[1], atoi(argv[2]));
    printf("sem_key: %x\n",sem_key);

    int sem_id = Semget(sem_key, 1, IPC_CREAT|IPC_EXCL|0755);//创建1个
    printf("sem_id: %d\n",sem_id);

    return 0;
}

删除信号量:IPC_RMID

#include"sem.h"

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
      printf("<Warning usage>:%s pathname proj_id\n",argv[0]);
      return -1;
    }
    key_t sem_key = Ftok(argv[1], atoi(argv[2]));

    int sem_id = Semget(sem_key, 0, 0);
    
    int ret = semctl(sem_id, 0, IPC_RMID);//删除0下标的信号量
    if(ret == -1)
    {
      printf("remove fail.");     
    }
    else
     printf("remove success.");

    return 0;
}   

 

设置信号量的值:SETVAL 
  因为前面只创建了一个,所以就只能给下标为0的SETVAL。

 

#include"sem.h"

int main(int argc, char *argv[])
{
    if(argc != 4)
    {
      printf("<Warning Usage>: %s pathname proj_id sem_val.\n",argv[0]);
      return -1;
    }
    key_t sem_key = Ftok(argv[1], atoi(argv[2]));

    int sem_id = Semget(sem_key, 0 , 0);

    union semun init;
    init.val = atoi(argv[3]);
    int ret = semctl(sem_id, 0, SETVAL, init);//给信号量数组下标为0的SETVAL

    if(ret == -1)
     printf("setval Error.\n");
    else
     printf("setval Success.\n");

    return 0;
}

   获取信号量的值:GETVAL

//GetValue

#include"sem.h"

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
      printf("<Warning Usage>: %s pathname proj_id.\n",argv[0]);
      return -1;
    }
    key_t sem_key = Ftok(argv[1], atoi(argv[2]));

    int sem_id = Semget(sem_key, 0, 0);
    
    int ret = semctl(sem_id, 0, GETVAL);

    if(ret == -1)
      printf("getval Error.\n");
    else
      printf("getval: %d\n",ret);

    return 0;
}

 

对semop()函数的解释,例如:

struct sembuf  info[3];

info[0].sem_num = 0;

info[0].sem_op =  -1;

info[0].sem_flg = 0; 

 

info[1].sem_num = 1;

info[1].sem_op = ..;

info[1].sem_flg = 0;

 

info[2].sem_num = 2;

...

如果你要操作三个信号量,semop(sem_id,  info, 3);即可

如果操作前两个:semop(sem_id, info, 2);

如果只是操作第二个:semop(sem_id, info[1], 1 )也可以。

 

对信号量进行“V“操作:可用资源数+1

//v_sem.c

#include"sem.h"

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
      printf("<Warning Usage>: %s pathname proj_id\n",argv[0]);
      return -1;
    }

    key_t sem_key = Ftok(argv[1], atoi(argv[2]));

    int sem_id = Semget(sem_key, 0, 0);
 
    struct sembuf info;
    info.sem_num = 0;
    info.sem_op  = 1;//类似于V操作
    info.sem_flg = 0;
    int ret = semop(sem_id, &info, 1);//对一个信号量进行操作
    if(ret == -1)
     printf("v Error.\n");
    else
     printf("v Success.\n");

    return 0;
}

 对信号量执行“p”操作:可用资源数 -1

///p_sem.c

#include"sem.h"

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
      printf("<Warning Usage>: %s pathname proj_id.\n",argv[0]);
      return -1;
    }

    key_t sem_key = Ftok(argv[1], atoi(argv[2]));
    
    int sem_id = Semget(sem_key, 0, 0);
    
    struct sembuf info;
    info.sem_num = 0;
    info.sem_op  = -1;//类似于P操作
    info.sem_flg = 0;

    int ret = semop(sem_id, &info, 1);
    if(ret == -1)
     printf("operator sem Error.\n");
    else
     printf("operator sem Success.\n");

    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux 之 System V信号量 的相关文章

  • 如何从子进程为父进程设置环境变量?

    如何从子进程为父进程设置环境变量 例如 我有父进程和子进程 子进程继承自父进程环境变量 TMP VARIABLE 777 如何将子进程中 TMP VARIABLE 的值更改为 999 使其值对父进程可见 因为 TMP VARIABLE 99
  • 错误:‘:’标记之前需要初始化程序

    我正在尝试编译一些 C 代码 可以在 Windows 上使用 Visual Studio 2012 进行编译 g 4 4 我有这段代码 const std string cnw restoreSession const std vector
  • 在linux中将数据“广播”到多个进程的规范方法?

    我有一个应用程序需要将数据流从一个进程发送到多个读取器 每个读取器都需要查看自己的流副本 这是相当高的速率 100MB s 并不罕见 因此我希望尽可能避免重复 在我的理想世界中 Linux 应该有支持多个读取器的命名管道 并为常见的单读取器
  • 很好的 C 库集合? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个很好的 ANSI C 库集合 用于处理向量 哈希映射 二进制树 字符串处理等 Try g
  • python中的多服务器监控/自动重启

    我有 2 个服务器程序 必须使用 GNU Screen 启动 我想使用基于 Python 的程序来强化这些服务器 防止崩溃 该程序启动每个屏幕会话 然后监视服务器进程 如果服务器进程崩溃 我需要 python 代码来终止无关的屏幕会话并再次
  • SDL/C++ OpenGL 程序,如何阻止 SDL 捕获 SIGINT

    我在用SDL http www libsdl org 用于在 Linux 上运行的 OpenGL 应用程序 我的问题是 SDL 正在捕获 SIGINT 并忽略它 这是一个痛苦 因为我正在通过屏幕会话进行开发 并且我无法使用 CTRL C 终
  • Zip 实用程序在 Linux 中每次都给我不同的 md5sum

    当我在 Linux 中压缩 Zip 2 31 同一个文件时 每次都会得到不同的校验和 如何保持上次的 md5sum 相同 我正在使用 yum 提供的最新 zip 更新 生成的存档不仅包含压缩文件数据 还包含 额外的文件属性 如参考zip 文
  • 在Linux服务器中安装ZLIB

    我要安装ZLIB http www techsww com tutorials libraries zlib installation installing zlib on ubuntu linux php在Linux服务器中 我的服务器帐
  • 32 位 x86 汇编中堆栈对齐的职责

    我试图清楚地了解谁 调用者或被调用者 负责堆栈对齐 64 位汇编的情况相当清楚 它是由caller 请参阅系统 V AMD64 ABI 第 3 2 2 节栈帧 输入参数区域的末尾应按 16 对齐 32 如果 m256 在堆栈 字节边界上传递
  • H.323,如何制作一个没有媒体的简单环。该脚本遵循 Q.931 设置,但仍然无法正常工作

    谁能帮我解决这个问题吗 当我发送此请求时 我在wireshark中看到数据包将发送到1720 tcp端口中的SJPhone 但 SJPhone 仍然没有响铃 我想让它响起 无论媒体 我非常感谢您的支持 我一定缺少消息协议细节来实现这个 请给
  • 如何在不需要设置 LD_LIBRARY_PATH shell 变量的情况下输入“cargo run”?

    我构建了一个 Rust 程序 通过 C 接口调用 C 函数 为了执行该程序 我必须运行 export LD LIBRARY PATH
  • Linux 汇编调试器

    我需要一个在 Linux 上进行汇编的调试器 我对 Linux 上缺乏调试器感到非常惊讶 它应该具有各种功能 例如显示寄存器等等 我会使用 GDB 但它对 NASM 不太友好 我宁愿让调试器具有英特尔语法 但我可以做出牺牲 我尝试过 kdb
  • 复制稀疏文件

    我正在尝试了解 Linux UNIX 低级接口 作为练习 我想编写一个代码 将一个有漏洞的文件复制到一个新文件 同样有漏洞 所以我的问题是 如何从第一个文件读取 而不是直到第一个洞 而是直到文件的最后 如果我没错的话 read 当到达第一个
  • 为什么运行一个空程序需要这么多指令?

    所以最近我了解到perfLinux 中的命令 我决定进行一些实验 因此我创建了一个空的 C 程序并测量了运行所需的指令数 echo int main gt emptyprogram c gcc O3 emptyprogram c o emp
  • 使用 C++ 更改终端字体大小

    我正在用 C 做一个小项目 在 Ubuntu 11 04 中 该程序是基于文本的 全部在 Gnome 终端中 我正在使用 ncurses 库来更改字体颜色 但我也想将不同大小的文本打印到终端 并且不知道如何使用 ncurses 来做到这一点
  • 对于位字段,使用 unsigned char 或 unsigned int 哪一个更好?为什么?

    我只想了解以下结构声明 哪一种更适合用于内存分配 为什么 如果是 unsigned char 和 unsigned int 那么填充又如何呢 struct data unsigned char a 3 unsigned char b 4 a
  • 如何删除警告:link.res包含输出部分;你忘了-T吗?

    我正在使用 fpc 编译器 我想删除此警告 我已经阅读了 fpc 的选项 但我找不到如何做到这一点 这可能吗 当我运行命令时出现 fpc foo pas out 目标操作系统 Linux for i386 编译 foo pas 链接 p2
  • 为什么每次运行应用程序时都必须使用导出来定义 LD_LIBRARY_PATH?

    我有一些使用一些共享库的代码 gcc 上的 c 代码 编译时 我必须使用 I 和 L 显式定义包含目录和库目录 因为它们不在标准位置 当我尝试运行代码时 出现以下错误 sync test sync test error while load
  • 在管道中使用“tee”时,如何将标准错误写入文件?

    我知道如何使用tee写入输出 标准输出 https en wikipedia org wiki Standard streams Standard output 28stdout 29 of aaa sh to bbb out 同时仍然在终
  • cURL 错误 28:5001 毫秒后解析超时

    我使用 WordPress 最近将我的网站从 cpanel 主机移动到带有 directadmin 面板的 Linux 服务器 转账后立即发现客户在通过EDD插件下载时出现以下错误 cURL 错误 28 5001 毫秒后解析超时 我也遇到了

随机推荐

  • numpy 矩阵复制

    纵向复制 横向复制
  • excel 中“万”字处理

    61 IF ISNUMBER FIND 34 万 34 M2 SUBSTITUTE M2 34 万 34 34 34 10000 M2 函数中的3个M2为需要处理单元格所在位置 结果展示如下
  • python groupby 不同列聚合

    dataframe 在groupby后有时候需要对不同的列按照不同的聚合方式聚合 聚合方法如图 xff1a num agg中输入各列数据的聚合方式 可用于多条件groupby
  • dataframe 中万字处理

    df 39 点赞 39 apply lambda x float str x replace 39 万 39 39 39 10000 if 39 万 39 in str x else x astype int
  • VSCode之CMake使用

    一 准备工作 下载 对应平台的VScode安装C 43 43 扩展 安装Cmake 工具扩展 并行需要安装 Cmake xff0c 编译器 xff0c 调试器和构建工具 cmake version 虽然咱们使用VSCode编辑代码 xff0
  • 运行apt-get update后出现错误

    一般错误是如下两种 xff1a 1 一般如果你的ubuntu是中文的设定了地区的 xff0c 错误是如下 xff1a W 无法下载http ppa launchpad net deluge team ppa ubuntu dists nat
  • 表达式求值(含括号的复杂运算)

    具体解析看注释 span class token macro property span class token directive keyword include span span class token string lt bits
  • HttpClient模拟登录总结(不能跳转及跳转后不能登录)

    最近在写一个模拟登录的程序 xff0c 从网上找了很多资料 xff0c 都没能有一个完整的例子可成功跳转登录后的页面 xff0c 现把我的代码拿来与大家分享一下 xff0c 希望可以帮到一些人吧 其原理是 xff1a 通过HttpClien
  • JestonTX2更新软件源

    JestonTX2刷机后需要更新软件源 更新软件源后 xff0c 才可以正常安装QT等软件 软件源记录文件放在以下文件中 cd etc apt source list 可以使用gedit打开此文件 sudo gedit etc apt so
  • Kali的下载安装详细过程

    1 什么是Kali xff1f Kali Linux是专门用于渗透测试的Linux操作系统 2 打开官网 Kali Linux Penetration Testing and Ethical Hacking Linux Distributi
  • 本地搭建GitLab地址不一致问题

    1 本地虚拟机用docker搭建Gitlab project clone 地址如下 xff1a 实际地址如下 xff1a http 192 168 56 51 root apacha backend 本来没在意这个问题 xff0c clon
  • 数据库笔试题(答案)

    一 填空题 每题2分 xff0c 共10分 1 索引字段值不唯一 xff0c 应该 使用 的索引类型为 普通索引 2 只有满足联接条件的记录才包含在查询结果中 xff0c 这种联接为 内联接 3 E R模型的组成包括那些 元素 实体 属性
  • mac时间机器占用大量系统盘空间且在访达中无法找到

    mac用时间机器备份到外置移动硬盘 xff0c 但是后来发现mac系统盘占用随之增加 经过研究发现 xff0c 时间机器备份是现在mac系统盘备份然后转移到移动硬盘 xff0c 而且系统盘中的备份文件是隐藏的 xff0c 所以在关于本机 x
  • android——降低gradle的版本、下载好gradle的包存放的位置

    一 降低gradle的版本 本文以gradle版本7 0 2改成6 3为例子 xff1a 1 在build gradle里面修改dependencies里面的 classpath 34 com android tools build gra
  • C语言十进制转八进制、十六进制以及十六进制转十进制、八进制

    以下程序的输出结果是 main int a 61 20 printf 34 d o x n 34 a a a 看到这个题目首先我们要明白 o 和 x代表的是什么意思 o代表的是输出该数字的八进制 x代表的是输出该数字的十六进制 1 题目给出
  • 解决Mybatis分页插件PageHelper自动添加limit导致分页失败问题

    目录 1 问题描述2 解决方案2 1 方案一2 2 方案二 3 完成效果4 一点困惑5 参考文献 1 问题描述 今天在完善项目的时候 xff0c 有一个需求就是给我的评论区实现分页显示评论数 xff0c 但是当自己运行的时候点击查看评论的时
  • STM32 HAL库 STM32CubeMX -- I2C(IIC)

    文章目录 一 I2C 协议简介I2C 物理层I2C协议层I2C架构通讯过程 二 STM32Cube MX配置三 I2C HAL库函数 一 I2C 协议简介 I2C 通讯协议 Inter xff0d Integrated Circuit 也就
  • 一个unsigned int 数的二进制表示中有多少个1

    这是一道面试题可以用以下的一些方案 第一种是很容易想到的采用循环的方式并且与1进行位与运算 xff0c 具体代码如下 1 unsigned int GetBitNumOfOne ByLoop1 unsigned int nValue 2 3
  • 网络安全(九)—— kali进行断网攻击

    kali进行断网攻击 1 查看是否有wlan0 wlan0mon网卡 ifconfig 2 开启监听 airmon ng start wlan0mon 3 扫描wifi airodump wlan0mon 攻击张书语 4 停止扫描 ctrl
  • Linux 之 System V信号量

    其实就是学几个函数的用法 xff1a ftok semget semctl semop 如果对哪个函数不熟悉就man 一下 xff0c 例如man semctl 下面是几个函数简单的实现代码 xff0c 自己可以实现一下 xff0c 助于理