文章目录

  • 1、信号量的概念
    • 1.1、二元信号量
  • 2、函数介绍
    • 2.1、semget函数
    • 2.2、semctl函数
    • 2.3、semop函数
  • 3、示例代码
  • 4、其他操作

1、信号量的概念

用于协调多个进程(包括但不限于父子进程)对共享数据对象的读/写。它不以传送数据为目的,主要是用来保护共享资源,保证共享资源在一个时刻只有一个进程独享。

1.1、二元信号量

信号量是一个特殊的变量,只允许进程对它进行等待信号和发送信号操作。最简单的信号量是取值0和1的二元信号量,这是信号量最常见的形式,1表示可以访问,0表示加锁

2、函数介绍

Linux中提供了一组函数用于操作信号量,程序中需要包含以下头文件:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

2.1、semget函数

semget函数用来获取或创建信号量

typedef unsigned int key_t
int semget(key_t key, int nsems, int semflg);
参数:key:是信号量的键值,是信号量在系统中的编号(一般用十六进制表示)nsems:是创建信号量集中信号量的个数,该参数只在创建信号量集时有效,这里固定填1。sem_flags:是一组标志,如果希望信号量不存在时创建一个新的信号量,可以和值IPC_CREAT做按位或操作。如果没有设置IPC_CREAT标志并且信号量不存在,就会返错(errno的值为2,No such file or directory)返回值:成功:返回信号量集的标识失败:-1示例代码:
1)获取键值为0x5000的信号量,如果该信号量不存在,就创建它,代码如下:
int semid=semget(0x5000,1,0640|IPC_CREAT);2)获取键值为0x5000的信号量,如果该信号量不存在,返回-1,errno的值被设置为2,代码如下:
int semid= semget(0x5000,1,0640);

2.2、semctl函数

该函数用来控制信号量(常用于设置信号量的初始值和销毁信号量

int semctl(int semid, int sem_num, int command, ...);
参数:semid:     semget函数返回值sem_num:  是信号量集数组上的下标,表示某一个信号量,填0cmd:        是对信号量操作的命令种类,常用的有以下两个:IPC_RMID:销毁信号量,不需要第四个参数;SETVAL:初始化信号量的值(信号量成功创建后,需要设置初始值),这个值由第四个参数决定。第四参数是一个自定义的共同体,如下:
// 用于信号灯操作的共同体。union semun{int val;struct semid_ds *buf;unsigned short *arry;};示例:
1)销毁信号量。semctl(semid,0,IPC_RMID);
2)初始化信号量的值为1,信号量可用。union semun sem_union;sem_union.val = 1;semctl(semid,0,SETVAL,sem_union);

2.3、semop函数

该函数有两个功能:1)等待信号量的值变为1,如果等待成功,立即把信号量的值置为0,这个过程也称之为等待锁;2)把信号量的值置为1,这个过程也称之为释放锁。

int semop(int semid, struct sembuf *sops, unsigned nsops);
参数:semid:semget函数返回的信号量标识sops:是一个结构体
struct sembuf
{short sem_num;   // 信号量集的个数,单个信号量设置为0。short sem_op;    // 信号量在本次操作中需要改变的数据:-1-等待操作;1-发送操作。short sem_flg;   // 把此标志设置为SEM_UNDO,操作系统将跟踪这个信号量。// 如果当前进程退出时没有释放信号量,操作系统将释放信号量,避免资源被死锁。
};nsops:是操作信号量的个数,即sops结构变量的个数,设置它的为1(只对一个信号量的操作)示例:
1)等待信号量的值变为1,如果等待成功,立即把信号量的值置为0;
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;
sem_b.sem_flg = SEM_UNDO;
semop(sem_id, &sem_b, 1);2)把信号量的值置为1。
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;
sem_b.sem_flg = SEM_UNDO;
semop(sem_id, &sem_b, 1);

3、示例代码

这段代码从严格来说是错误的,因为我没有加错误处理,这样子写主要是为了理解,大家看一下加深理解就好,

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>union semun  // 用于信号量操作的共同体。
{int val;struct semid_ds *buf;unsigned short  *arry;
};int main()
{int semid = semget(0x5000,1,0644|IPC_CREAT);            // 创建或获取信号量printf("semid:%d\n",semid);                             // 信号量idunion semun sem_union;                                  // 设置信号量初始值sem_union.val = 1;semctl(semid,0,SETVAL,sem_union);int value = semctl(semid,0,GETVAL);                     // 获取当前信号量的值printf("value:%d\n",value);struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_op = -1;sem_b.sem_flg = SEM_UNDO;   semop(semid,&sem_b,1);                                 // 相当于加锁操作// 设置完之后信号量值就变成0了,标识持有锁int value1 = semctl(semid,0,GETVAL);                   // 获取一下当前信号量值,当前值就是0printf("value1:%d\n",value1);sem_b.sem_num = 0; sem_b.sem_op = 1;sem_b.sem_flg = SEM_UNDO;   semop(semid,&sem_b,1);                                  // 释放锁操作// 设置完,信号量值为1int value2 = semctl(semid,0,GETVAL);                    // 获取当前信号量值,当前值就是1printf("value1:%d\n",value2);return 0;
}

4、其他操作

1、用ipcs -s可以查看系统的信号量,内容有键值(key),信号量编号(semid),创建者(owner),权限(perms),信号量数(nsems)。2、用ipcrm sem 信号量编号,可以手工删除信号量

Linux C 信号量相关推荐

  1. Linux系统信号量实现生产者-消费者问题

    Linux系统信号量实现生产者-消费者问题 实现代码 #include<bits/stdc++.h> #include<unistd.h> #include<pthrea ...

  2. Linux操作系统-信号量

    信号量也属于一种进程间通信的机制,与其他的进程间通信不同,信号量不是用来传输数据的,而是用来进程间同步与互斥.除此之外,信号量还可以实现线程间的互斥. 信号量是什么? 信号量的本质是一个计数器. 一个 ...

  3. linux c 信号量简介

    信号量的分类 在学习 IPC 信号量之前,让我们先来了解一下 Linux 提供两类信号量: 内核信号量,由内核控制路径使用. 用户态进程使用的信号量,这种信号量又分为 POSIX 信号量和 Syste ...

  4. linux 内核信号量与用户态信号量(system v,信号量在Linux多线程机制中的应用

    [摘 要]本文以信号量原理为基础,重点阐述信号量在Linux多线程同步机制中的实现特色. [关键词]信号量:Linux:多线程:同步 1 信号量 1965年E. W. Dijkstra首次提出信号量的 ...

  5. linux 信号量锁 内核,Linux内核信号量互斥锁应用

    主要介绍了Linux 内核关于信号量,互斥锁等的应用 内核同步机制-信号量/互斥锁/读-写信号量 sema ,mutex ,rwsem 信号量 通用信号量 用户类进程之间使用信号量(semaphore ...

  6. linux 进程间通信-信号量(semagpore)

    linux 信号量是一种IPC(Inter-Process Communication)进程间通信,它是System V semagpore ,是一种计数器:代笔了进程对资源的占用和释放:它的实现机制 ...

  7. Linux内核信号量:二值信号量/互斥信号量,计数信号量,读写信号量

    <semaphore信号量:一个简单的示例程序>用户态程序 目录 概念 应用场景 使用方法 内核信号量的构成 信号量的API 初始化 PV操作 获取信号量(P) 释放内核信号量(V) 补充 ...

  8. Linux 进程间通信 - 信号量

    0. 前言    进程是一个独立的资源管理单元,不同进程间的资源是独立的,不能在一个进程中访问另一个进程的用户空间和内存空间.但是,进程不是孤立的,不同进程之间需要信息的交互和状态的传递,因此需要进程 ...

  9. Linux进程间通信信号量

    在多进程的编程环境,进程往往需要共享某些资源,比如共享内存,文件.在多个进程同时对这些共享资源操作时候,可能会引起冲突.为了更好的控制对资源的访问,linux提供了一种成为信号量的机制,首先要认识到P ...

  10. linux申请信号量,linux 信号量

    https://www.jianshu.com/p/6e72ff770244 无名信号量 只适合用于一个进程的不同线程 #include #include #include #include #inc ...

最新文章

  1. HP ProLiant服务器收集日志的方法
  2. 计算机网络·用户代理和浏览器 发送邮件分别需要的协议
  3. tcp协议中的长连接和短连接服务器,谈谈HTTP协议中的短轮询、长轮询、长连接和短链接...
  4. 前端学习(2947):node.js使用
  5. QT高级编程之QT基本概览
  6. 计算机应用基础自考,自考计算机应用基础
  7. 主成分分析PCA案例及原理
  8. python和ui设计,PySide2相当于PyQt5的loadUiType(),用于在UI设计中动态混合
  9. `find -name`模式匹配多个模式
  10. 计算机专业实习心得,计算机毕业实习心得体会范本5篇
  11. APP测试点总结(表格形式)
  12. 【广东大学生网络攻防大赛-WriteUp(非官方)】Web | in
  13. 主板电源开关接口图解_全程图解:手把手教你主板各种插针接口与机箱(电源)的接法...
  14. java kinect_使用java来做Kinect开发
  15. 无意间看到这样一首歌 Take me to your heart
  16. (每日一练c++)有效的数独
  17. java 读取 解析微软Project .mpp 文件到甘特图
  18. 用ado把excel数据写入oracle,如何将excel表格数据导入到oracle数据库对应的表中?!oracle导出excel文件...
  19. 常见3D游戏物理引擎总结
  20. 我们为什么生病:达尔文医学的新观念

热门文章

  1. 用算法去扫雷(go语言)
  2. 简易散列表实现电话号码查询系统
  3. FishC笔记—26 讲 字典:当索引不好用时2
  4. 神经网络控制系统设计,神经网络技术及其应用
  5. win10商店下载位置_教你win10设置应用商店中应用默认安装位置教程
  6. FileZilla客户端使用遇到的问题
  7. C语言函数 思维导图
  8. Apizza-流程测试模式
  9. 路由器的软件测试,路由器测试方法 - 软件测试网 _领测软件测试网站-中国软件测试技术第一门户...
  10. 高等数学(第七版)同济大学 习题2-4 个人解答