Linux C 信号量
文章目录
- 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 信号量相关推荐
- Linux系统信号量实现生产者-消费者问题
Linux系统信号量实现生产者-消费者问题 实现代码 #include<bits/stdc++.h> #include<unistd.h> #include<pthrea ...
- Linux操作系统-信号量
信号量也属于一种进程间通信的机制,与其他的进程间通信不同,信号量不是用来传输数据的,而是用来进程间同步与互斥.除此之外,信号量还可以实现线程间的互斥. 信号量是什么? 信号量的本质是一个计数器. 一个 ...
- linux c 信号量简介
信号量的分类 在学习 IPC 信号量之前,让我们先来了解一下 Linux 提供两类信号量: 内核信号量,由内核控制路径使用. 用户态进程使用的信号量,这种信号量又分为 POSIX 信号量和 Syste ...
- linux 内核信号量与用户态信号量(system v,信号量在Linux多线程机制中的应用
[摘 要]本文以信号量原理为基础,重点阐述信号量在Linux多线程同步机制中的实现特色. [关键词]信号量:Linux:多线程:同步 1 信号量 1965年E. W. Dijkstra首次提出信号量的 ...
- linux 信号量锁 内核,Linux内核信号量互斥锁应用
主要介绍了Linux 内核关于信号量,互斥锁等的应用 内核同步机制-信号量/互斥锁/读-写信号量 sema ,mutex ,rwsem 信号量 通用信号量 用户类进程之间使用信号量(semaphore ...
- linux 进程间通信-信号量(semagpore)
linux 信号量是一种IPC(Inter-Process Communication)进程间通信,它是System V semagpore ,是一种计数器:代笔了进程对资源的占用和释放:它的实现机制 ...
- Linux内核信号量:二值信号量/互斥信号量,计数信号量,读写信号量
<semaphore信号量:一个简单的示例程序>用户态程序 目录 概念 应用场景 使用方法 内核信号量的构成 信号量的API 初始化 PV操作 获取信号量(P) 释放内核信号量(V) 补充 ...
- Linux 进程间通信 - 信号量
0. 前言 进程是一个独立的资源管理单元,不同进程间的资源是独立的,不能在一个进程中访问另一个进程的用户空间和内存空间.但是,进程不是孤立的,不同进程之间需要信息的交互和状态的传递,因此需要进程 ...
- Linux进程间通信信号量
在多进程的编程环境,进程往往需要共享某些资源,比如共享内存,文件.在多个进程同时对这些共享资源操作时候,可能会引起冲突.为了更好的控制对资源的访问,linux提供了一种成为信号量的机制,首先要认识到P ...
- linux申请信号量,linux 信号量
https://www.jianshu.com/p/6e72ff770244 无名信号量 只适合用于一个进程的不同线程 #include #include #include #include #inc ...
最新文章
- HP ProLiant服务器收集日志的方法
- 计算机网络·用户代理和浏览器 发送邮件分别需要的协议
- tcp协议中的长连接和短连接服务器,谈谈HTTP协议中的短轮询、长轮询、长连接和短链接...
- 前端学习(2947):node.js使用
- QT高级编程之QT基本概览
- 计算机应用基础自考,自考计算机应用基础
- 主成分分析PCA案例及原理
- python和ui设计,PySide2相当于PyQt5的loadUiType(),用于在UI设计中动态混合
- `find -name`模式匹配多个模式
- 计算机专业实习心得,计算机毕业实习心得体会范本5篇
- APP测试点总结(表格形式)
- 【广东大学生网络攻防大赛-WriteUp(非官方)】Web | in
- 主板电源开关接口图解_全程图解:手把手教你主板各种插针接口与机箱(电源)的接法...
- java kinect_使用java来做Kinect开发
- 无意间看到这样一首歌 Take me to your heart
- (每日一练c++)有效的数独
- java 读取 解析微软Project .mpp 文件到甘特图
- 用ado把excel数据写入oracle,如何将excel表格数据导入到oracle数据库对应的表中?!oracle导出excel文件...
- 常见3D游戏物理引擎总结
- 我们为什么生病:达尔文医学的新观念