信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问编程时可根据操作信号量值的结果判断是否对公共资源具有访问权限,当信号量值大于0时,则可以访问,否则将阻塞。PV原语是对信号量的操作,一次P操作使信号量减1,一次V操作使信号量加1;
信号量相关API如下:
int sem_init(sem_t *sem,int pshared,unsigned int value); // 初始化
int sem_destroy(sem_t *sem); // 销毁
int sem_wait(sem_t *sem); // 资源减少1
int sem_trywait(sem_t *sem); // 非阻塞减1
int sem_post(sem_t *sem); // 资源增加1
int sem_getvalue(sem_t *sem,int *val) // 获取信号量的值
栗子:
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int number = 1;
sem_t sem;
void* thread_fun1(void *arg){
sem_wait(&sem);
number++;
printf("thread_fun1: number = %d\n",number);
sem_post(&sem);
}
void* thread_fun2(void *arg)
{
sem_wait(&sem);
number--;
printf("thread2_fun2: number = %d\n",number);
sem_post(&sem);
}
int main(int argc, char** argv) {
pthread_t id1,id2;
sem_init(&sem,0,1);
pthread_create(&id1,NULL,thread_fun1,NULL);
pthread_create(&id2,NULL,thread_fun2,NULL);
pthread_join(id1,NULL);
pthread_join(id2,NULL);
sem_destroy(&sem);
return 0;
}
输出:
thread_fun1: number = 2
thread2_fun2: number = 1
栗子2:
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
sem_t bindSem;
void* show(void* arg);
int main(int argc, char** argv) {
int res = 0;
res = sem_init(&bindSem,0,0);
if(res) {
printf("Semaphore initialization failed...\n");
exit(EXIT_FAILURE);
}
pthread_t threadHelloWorld;
// 第一个参数是要绑定的线程对象
// 第二个参数是可以被用来设置线程属性,一般使用NULL
// 第三个参数需要绑定的函数名称
// 第四个参数是函数传入的参数
res = pthread_create(&threadHelloWorld,NULL,show,NULL);
if(res) {
printf("Thread creation failed...\n");
exit(EXIT_FAILURE);
}
while(1) {
sem_post(&bindSem);
printf("In main , sleep several seconds...\n");
sleep(1);
}
void *threadResult;
res = pthread_join(threadHelloWorld, &threadResult);
if (res) {
printf("Thread join failed...\n");
exit(EXIT_FAILURE);
}
return 0;
}
void* show(void* arg) {
while(1) {
sem_wait(&bindSem);
printf("Hello World\n");
}
}
输出:
In main , Hello World
sleep several seconds...
In main , sleep several seconds...
Hello World
In main , sleep several seconds...
Hello World
In main , sleep several seconds...
Hello World