信号量主要用于进程间(不是线程)的互斥,通过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. 用js触发CSS3-transition过渡动画

    用js触发CSS3-transition过渡动画 经过这几天的工作,让我进一步的了解到CSS3的强大,原本许多需要js才能实现的动画效果,现在通过CSS3就能轻易实现了,但是CSS3也有自身的不足,例 ...

  2. IBatisNet -- 保护你的配置文件及映射文件信息

    通常情况下我们在使用IBatisNet的时候,配置文件和映射文件都是暴露在外的,如果能进入到服务器,那么你的程序的操作数据库的SQL语句,数据库连接字符串等信息都将很轻松的被看到,这样是很危险的.然而 ...

  3. 【无私分享:ASP.NET CORE 项目实战(第九章)】创建区域Areas,添加TagHelper

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 在Asp.net Core VS2015中,我们发现还有很多不太简便的地方,比如右击添加视图,转到试图页等功能图不见了,虽然我 ...

  4. Android 的进程和线程

    进程和线程 如果某个应用程序组件是第一次被启动,且这时应用程序也没有其他组件在运行,则android系统会为应用程序创建一个包含单个线程的linux进程.默认情况下,同一个应用程序的所有组件都运行在同 ...

  5. hibernate 中根据id删除一条记录的语句

    qid name like content 1 A 1 the first text 2 B 2 the Second text 1 C 3 the Third text 如上表所示,当我们需要某个q ...

  6. 2015年软件测试STATE报告

    STATE OF TESTING 2015 Report 测试职业的地理位置分配 大部分有5年以上工作经验 大部分是Test Leader   测试工程师角色   测试工程师怎么工作的? 测试中的软件 ...

  7. DNS原理及其解析过程 精彩剖析

    本文章转自下面:http://369369.blog.51cto.com/319630/812889 DNS原理及其解析过程 精彩剖析 网络通讯大部分是基于TCP/IP的,而TCP/IP是基于IP地址 ...

  8. IoC组件~Autofac将多实现一次注入,根据别名Resove实例

    回到目录 对于IoC容器来说,性能最好的莫过于Autofac了,而对于灵活度来说,它也是值得称赞的,为了考虑系统的性能,我们经常是在系统初始化于将所有依赖注册到容器里,当需要于根据别名把实现拿出来,然 ...

  9. react-echarts之折线图的显示

    react中想要实现折线图和饼图的功能,需要引入react-echarts包,然后再实现折线图的功能.我这里引用的版本是:0.1.1.其他的写法参echarts官网即可.下面详细讲解的是我在react ...

  10. 后端Java工程师常用JavaScript_DOM

    JavaScript [1]事件 ①用户操作网页或者浏览器所发生的交互行为称为事件.比如:点击按钮,最小化窗口,修改文本框内容等. ②JS为我们定义许多浏览器中的事件.比如:单击(onclick).双 ...