信号量主要用于进程间(不是线程)的互斥,通过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. Hibernate(1)——数据访问层的架构模式

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 数据库的概念.逻辑.数据模型概念 应用程序的分层体系结构发展 MVC设计模式与四层结构的对应关系 持久层的设 ...

  2. 移动端web开发的那些坑

    1.为非a列表项添加触感样式 通过js注册touchstart和touchend事件,添加触感class的方式, 有个坑,低版本的Android浏览器,经常触发不到touchend,需要再额外注册一个 ...

  3. php后台增删改跳转

    php登录页面: <h1>登录界面</h1> <form action="dengluchuli.php" method="post&quo ...

  4. 用eclipse开发项目时遇到的常见错误整理,和配套解决方案(1)

    01. MyEclipse项目导入eclipse后,怎么发布不了? 今天导入了之前的一个MyEclipse项目,更改jdk后,发现发布不了.解决方案如下: 打开项目根目录,找到.settings文件夹 ...

  5. Grunt学习使用

    原文地址:Grunt学习使用必看 grunt简介神马的不多说,到处一大堆. 我只说说我已经实现了的代码. 按照官方的教程 相信已经配置好了,接下来说 package.json 和 Gruntfile. ...

  6. UWP简单示例(一):快速合成音乐MV

    准备 IDE:Visual Studio 2015 为你的项目安装Nuget包 SharpDx.XAudio2 为你的项目安装Nuget包 Win2D.UWP 了解并学习:Win2D官方博客 了解并学 ...

  7. TeamCity : Build 版本控制系统配置

    VCS (版本控制系统) 是用来跟踪项目源文件版本变化的系统.它还有其它的名字,比如 SCM(源代码管理).当前 TeamCity 内置支持的 VCS 类型有:Git, Subversion, Mer ...

  8. mysql+mycat搭建稳定高可用集群,负载均衡,主备复制,读写分离

    数据库性能优化普遍采用集群方式,oracle集群软硬件投入昂贵,今天花了一天时间搭建基于mysql的集群环境. 主要思路 简单说,实现mysql主备复制-->利用mycat实现负载均衡. 比较了 ...

  9. Windows 10 安装 Sql Server 2014 反复提示需要安装 .NET Framework 3.5 SP1 的解决方案

    一.首先安装.NET Framework 3.5: 离线安装方式: 1.装载相对应的系统安装盘,我是Windows 10 x64 企业版,所以装载Windows 10 x64 企业版安装镜像ISO,盘 ...

  10. C#限速下载网络文件

    代码: using System; using System.Collections.Concurrent; using System.Collections.Generic; using Syste ...