之前一直误以为信号量初始化的时候那个初始化的值是信号量的“容量”,昨天同事指出了我的错误,最初我是不相信的,经过以下代码实践,证明了我的错误:
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
彻底纠正了我一直以来的认知错误。