文档章节

信号量有没有容量限制?

锟斤拷烫烫烫
 锟斤拷烫烫烫
发布于 07/22 18:25
字数 615
阅读 12
收藏 0

之前一直误以为信号量初始化的时候那个初始化的值是信号量的“容量”,昨天同事指出了我的错误,最初我是不相信的,经过以下代码实践,证明了我的错误:

Java版:

import java.util.concurrent.Semaphore;

public class Driver {

    private Semaphore semaphore;

    public Driver(int num){
        semaphore = new Semaphore(num);
    }

    /**
     * [driveCar description]
     * 假设:我们假定信号量初始化的时候,构造函数中的值是信号量的 容量
     * 验证:如果设置容量为 1 在释放第一次之后 第二次释放将是非法操作 一定会报相关错误
     */

    public void driveCar() {
        try {
            semaphore.acquire();//获取信号量
            int permits = semaphore.availablePermits();//当前可用的信号量
            System.out.println("1permits is "+permits);
            semaphore.release();//释放信号量
            permits = semaphore.availablePermits();
            System.out.println("2permits is "+permits);
            semaphore.release();//再次释放信号量
            permits = semaphore.availablePermits();
            System.out.println("3permits is "+permits);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

编写测试类如下:

class Test {
	public static void main(String[] args) {
		int num = Integer.valueOf(args[0]);
		Driver driver = new Driver(num);
		driver.driveCar();
	}
}

执行测试:java test 1得到结果如下

1permits is 0
2permits is 1
3permits is 2

由此说明,每次信号量释放的时候给信号量的值加1,但是其初始化的值,并不影响这个加1的操作,在 Java 中这个容量固定的假设不成立。

于是我还是不死心,继续去验证了 C 语言版本的,代码如下:

#include <semaphore.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
sem_t binSem;
int sval = 0;

int main(int argc,char* argv[])
{
    int res = 0;
    int num = (int)(*argv[1]) - 48;
    printf("num is %d\n",num);
    res = sem_init(&binSem,1,num);
    
    if (res) {
         printf("Semaphore initialization failed!!\n");
         //exit(EXIT_FAILURE);
     }

    sem_wait(&binSem);
    sem_getvalue(&binSem, &sval);
    printf("1permits %d\n",sval);

    sem_post(&binSem);
    sem_getvalue(&binSem, &sval);
    printf("2permits %d\n",sval);

    sem_post(&binSem);
    sem_getvalue(&binSem, &sval);
    printf("3permits %d\n",sval);
}

编译的时候一定要加 -pthread 选项,不然编译会报类似如下错误:


/tmp/cc2tarEg.o: In function `main':
sem.c:(.text+0x51): undefined reference to `sem_init'
sem.c:(.text+0x6e): undefined reference to `sem_wait'
sem.c:(.text+0x7d): undefined reference to `sem_getvalue'
sem.c:(.text+0x9e): undefined reference to `sem_post'
sem.c:(.text+0xad): undefined reference to `sem_getvalue'
sem.c:(.text+0xce): undefined reference to `sem_post'
sem.c:(.text+0xdd): undefined reference to `sem_getvalue'

这里我是这么编译的:gcc sem.c -pthread -o sem

然后执行 ./sem 1

输出:

num is 1
1permits 0
2permits 1
3permits 2

彻底纠正了我一直以来的认知错误。

© 著作权归作者所有

共有 人打赏支持
锟斤拷烫烫烫
粉丝 3
博文 31
码字总数 7782
作品 0
信阳
后端工程师
理解PV操作和信号量

对于信号量,可以认为是一个仓库,有两个概念,容量和当前的货物个数。 P操作从仓库拿货,如果仓库中没有货,线程一直等待,直到V操作,往仓库里添加了货物,为了避免P操作一直等待下去,会有...

抢地主
2016/06/23
28
0
【PHP】如何优雅的杀死PHP的死循环(常驻进程)

在日常开发的过程中,遇到一个问题,就是 有这么一个常驻进程,每隔6秒,干一些事情,这个时候,突然出了一些意外状况或者要迭代版本,得先给这个进程停掉,打断循环退出。如果直接kill掉,那...

qq_28602957
2017/10/31
0
0
zephyr笔记 2.4.1 信号量

1 前言 信号量是实现传统计数信号量的内核对象。 我正在学习 Zephyr,一个很可能会用到很多物联网设备上的操作系统,如果你也感兴趣,可点此查看帖子zephyr学习笔记汇总。 2 概念 可以定义任...

iotisan
04/28
0
0
swoole 中的锁及其应用

date: 2017-12-25 01:42:00 title: swoole 中的锁及其应用 时间不早了, 尽量言简意赅一些. 怎么快速学习锁: 锁是什么 -> 锁的概念 为什么要用锁 -> 锁的使用场景 怎么使用锁 -> show me the...

daydaygo
2017/12/26
0
0
第15章 进程间通行 15.6 XSI IPC 15.7 消息队列

15.6 XSI IPC (1)3种称作XSI IPC的IPC是: 1)消息队列 2)信号量 3)共享存储器 (2)标识符和键 1)标识符:是一个非负整数,用于引用IPC结构。是IPC对象的内部名。 2)键:IPC对象的外部...

fxdhdu
2015/10/23
79
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

【七】组合Action

本章描述了常用定义Action的方法。 自定义action builders 我们在action一章已经看过如何声明一个action——有request parameter、无request parameter、有body parser等等。你可以在 asynch...

Landas
25分钟前
0
0
Spring Boot实战之基础回顾

本文作者: 吴伟祥 本文链接: https://wuweixiang.cn/2018/08/21/Spring-Boot实战之基础回顾/ 版权声明: 本博客所有文章除特别声明外均为原创,采用CC BY-NC-SA 4.0 许可协议。转载请在文章开...

吴伟祥
25分钟前
0
0
OAuth认证开发

提示: 以下测试是基于项目安装成功,初始化数据库(initial_db.ddl, oauth.ddl, initial_data.ddl)后的测试, 也可在页面上点击"client_details"菜单里进行测试 方式1:基于浏览器 (grant_type=...

舒文joven
34分钟前
1
0
第二章-对象及变量的并发访问-第二篇

锁对象的改变 请阅读如下代码 public class MainClass { private String lock = "123"; public void printStringB() { try { synchronized (lock) { ......

简心
38分钟前
0
0
日志中记录代理IP以及真实客户端、apache只记录指定URI的日志

apache 日志中记录代理IP以及真实客户端 默认情况下log日志格式为: LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined 其中%h 是记录访问者的IP,如果在web的前...

李超小牛子
46分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部