信号量主要用于进程间(不是线程)的互斥,通过sem_p()函数加锁使用资源,sem_v函数解锁释放资源,在加锁期间,CPU从硬件级别关闭中断,防止pv操作被打断。
semget函数
int semget(key_t key, int nsems, int semflg);
--功能:用来创建和访问一个信号量集
--参数
key:信号集的key值
nsems:信号集中信号量的个数
semflg:由九个权限标志构成,他们的用法和创建文件时使用的mode模式标志是一样的
--返回值:成功返回一个非负整数,即该信号集的标识码,失败返回-,并且更新errno
shmctl函数
int semctl(int semid, int semnum, int cmd, ...);
--功能:用于控制信号量集
--参数
semid:由semget返回的信号集标识码
semnum:信号集中信号量的序号(信号量的序号从0开始,和数组类似)
cmd:将要采取的动作(有5个可取值)
最后一个参数根据命令不同而不同
--返回值:成功返回0;失败返回-1并且更新errno
semop函数
int semop(int semid, struct sembuf *sops, unsigned nsops);
--功能:
--参数
semid:semget函数的返回值
sops:是个指向一个结构体的指针
nsops:信号量的个数
--返回值:成功返回0,失败返回-,并且更新errno
semop函数续
--sembuf结构体
struct sembuf
{
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
sem_num是信号量的编号
sem_op是信号量一次PV操作是加减的数值,一般只会用到两个值,一个是"-1",也就是P操作,等待信号量变得可用;另一个是"+1",也就是V操作,发出信号量已经变得可用。
sem_flg的两个取值IPC_NOWAIT或SEM_UNDO,SEM_UNDO是进程完成P操作后直接被终止了,那么系统会自动执行V操作,恢复成默认值
//信号量API
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> //这个定义不可少
union semun
{
int val; // Value for SETVAL
struct semid_ds *buf; // Buffer for IPC_STAT, IPC_SET
unsigned short *array; // Array for GETALL, SETALL
struct seminfo *__buf; // Buffer for IPC_INFO(Linux-specific)
}; /**
* sem_setval - 设置信号量的资源值
* semid:由semget返回的信号集标识码
* val:资源值
* 成功返回0,失败返回-1
* */
int sem_setval(int semid, int val)
{
int ret = ;
//union semun必须自定义
union semun su;
su.val = val;
//semctl()第二个参数是序号,这里取第一个信号量
ret = semctl(semid, , SETVAL, su);
if (ret == -)
{
perror("semctl() err");
}
return ret;
} /**
* sem_setval - 获取信号量的资源值
* semid:由semget返回的信号集标识码
* 成功返回可用资源值,失败返回-1
* */
int sem_getval(int semid)
{
int ret = ;
//semctl()第二个参数是序号,这里取第一个信号量
//当使用GETVAL命令时,调用中的最后一个参数被忽略
//成功返回该信号量的可用资源值
ret = semctl(semid, , GETVAL, );
if (ret == -)
{
perror("semctl() err");
}
printf("getval=%d\n", ret);
return ret;
} /**
* sem_p - 信号量P操作
* semid:由semget返回的信号集标识码
* 成功返回0,失败返回-1
* */
int sem_p(int semid)
{
int ret=;
//通过struct sembuf结构体的sem_op属性设置P操作
//sem_flg默认设置为0
struct sembuf sbuf={,-,};
ret=semop(semid,&sbuf,);
if(ret==-)
perror("semop() err");
return ret;
} /**
* sem_v - 信号量V操作
* semid:由semget返回的信号集标识码
* 成功返回0,失败返回-1
* */
int sem_v(int semid)
{
int ret=;
//通过struct sembuf结构体的sem_op属性设置P操作
//sem_flg默认设置为0
struct sembuf sbuf={,,};
ret=semop(semid,&sbuf,);
if(ret==-)
perror("semop() err");
return ret;
} int main()
{
//创建或者访问信号量集
int semid = ;
//第二个参数创建几个信号量
semid = semget(0x1234, , | IPC_CREAT | IPC_EXCL);
if (semid == -)
{
if (errno == EEXIST)
{
printf("该信号量集已经存在!\n");
semid = semget(0x1234, , );
} else
{
perror("semget() err");
return -;
}
}
//设置第0个信号量的s(可用资源)的值为1
sem_setval(semid, );
sem_getval(semid);
sem_p(semid);
printf("dddddd\n");
sem_v(semid);
return ;
}

Linux 信号量详解一的更多相关文章

  1. Linux信号量详解

    1.什么是信号量信号量是一种特殊的变量,访问具有原子性.只允许对它进行两个操作:1)等待信号量当信号量值为0时,程序等待:当信号量值大于0时,信号量减1,程序继续运行.2)发送信号量将信号量值加1. ...

  2. Linux 系统结构详解

    Linux 系统结构详解 Linux系统一般有4个主要部分: 内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用系统 ...

  3. Linux Ptrace 详解

    转 https://blog.csdn.net/u012417380/article/details/60470075 Linux Ptrace 详解 2017年03月05日 18:59:58 阅读数 ...

  4. [转帖]Linux文件系统详解

    Linux文件系统详解 https://www.cnblogs.com/alantu2018/p/8461749.html 贼复杂.. 从操作系统的角度详解Linux文件系统层次.文件系统分类.文件系 ...

  5. Linux命令详解之—tail命令

    tail命令也是一个非常常用的文件查看类的命令,今天就为大家介绍下Linux tail命令的用法. 更多Linux命令详情请看:Linux命令速查手册 Linux tail命令主要用来从指定点开始将文 ...

  6. Linux命令详解之—less命令

    Linux下还有一个与more命令非常类似的命令--less命令,相比于more命令,less命令更加灵活强大一些,今天就给大家介绍下Linux下的less命令. 更多Linux命令详情请看:Linu ...

  7. Linux命令详解之—more命令

    Linux more命令同cat命令一样,多用来查看文件内容,本文就为大家介绍下Linux more命令的用法. 更多Linux命令详情请看:Linux命令速查手册 Linux的more命令类似 ca ...

  8. 【转】linux命令详解:md5sum命令

    [转]linux命令详解:md5sum命令 转自:http://blog.itpub.net/29320885/viewspace-1710218/ 前言 在网络传输.设备之间转存.复制大文件等时,可 ...

  9. Linux命令详解之—cat命令

    cat命令的功能是连接文件或标准输入并打印,今天就为大家介绍下Linux中的cat命令. 更多Linux命令详情请看:Linux命令速查手册 Linux 的cat命令通常用来显示文件内容,也可以用来将 ...

随机推荐

  1. 浅谈css的伪元素::after和::before

    css中的::after和::before已经被大量地使用在我们日常开发中了,使用他们可以使我们的文档结构更加简洁.但是很多人对::after和::before仍不是特别了解,究竟他们是做什么的?如何 ...

  2. 微信小程序的应用及信息整合,都放到这里了

    微信小程序终于开始公测了,这篇文章也终于可以发布了. 这篇文章可以说是微信小程序系列三部曲最后一篇.8 月份,小程序推出前,我写了<别开发 app 了>详细阐述了为什么创业应该放弃原生 a ...

  3. 抽象类 VS 接口

    引言 接口和抽象类是面向对象编程(OOP, Object Oriented programming)中两个绕不开的概念,二者相似而又有所不同.接下来,我们来了解二者的概念并比较它们的异同. 什么是抽象 ...

  4. WinForm操作隐藏的小知识点

    这次的项目需要使用Winform来实现,我们使用的是CSkin的皮肤.文章主要记录使用过程中遇到的小问题,也是楼主网上查找很久才找到的,这里总结下. 插件地址: 使用SKinDataGridView出 ...

  5. jquery时间日期三级联动

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs ...

  6. Button 模板和样式

    <Style TargetType="{x:Type Button}"> <Setter Property="FontFamily" Valu ...

  7. 搜狗输入法linux安装 以及 12个依赖包下载链接分享

    搜狗输入法linux安装版,先安装各种依赖包,大概12个依赖,可能中途还需要其他依赖,可以效仿解决依赖问题.如图这12个文件要是手动点击下载,那也太笨点了,我们要用shell命令批量下载.命令如下:w ...

  8. JAVA大数据数组排序

    对于数据排序大家肯定见过不少,选择排序或者冒泡排序等等,今天我们要做的是快速排序 + 直接插入排序来对大数据(1000万以上)进行排序,下面我们分别来看看这两种排序规则 1, 直接插入排序 (1)基本 ...

  9. (转)ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 的解决方法

    早上同事用PL/SQL连接虚拟机中的Oracle数据库,发现又报了"ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务"错误,帮其解决后,发现很多人遇到过这样的问 ...

  10. 如何用Web技术开发Windows Form应用

    现在H5很热,很多互联网公司的产品都采用混合编程,其中各个平台客户端的“壳”为原生控件,但是内容很多都是Web网页,因此可以做出很多炫酷的效果.随着Node.js和Ionic等框架的出现,现在感觉Ja ...