(1)信号量说明
在第8 章中已经讲到,信号量也就是操作系统中所用到的PV 原语,它广泛用于进程或
线程间的同步与互斥。信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的
访问。这里先来简单复习一下PV原语的工作原理。
PV原语是对整数计数器信号量sem的操作。一次P操作使sem减一,而一次V操作使
sem 加一。进程(或线程)根据信号量的值来判断是否对公共资源具有访问权限。当信号量
sem 的值大于等于零时,该进程(或线程)具有公共资源的访问权限;相反,当信号量sem
的值小于零时,该进程(或线程)就将阻塞直到信号量sem的值大于等于0 为止。
PV 原语主要用于进程或线程间的同步和互斥这两种典型情况。若用于互斥,几个进程
(或线程)往往只设置一个信号量sem,它们的操作流程如图9.2 所示。
当信号量用于同步操作时,往往会设置多个信号量,并安排不同的初始值来实现它们之
间的顺序执行
(2)函数说明
Linux 实现了POSIX 的无名信号量,主要用于线程间的互斥同步。这里主要介绍几个常
见函数。
· sem_init用于创建一个信号量,并能初始化它的值。
· sem_wait和sem_trywait相当于P操作,它们都能将信号量的值减一,两者的区别在
于若信号量小于零时,sem_wait将会阻塞进程,而sem_trywait则会立即返回。
· sem_post相当于V操作,它将信号量的值加一同时发出信号唤醒等待的进程。
· sem_getvalue用于得到信号量的值。
· sem_destroy用于删除信号量。
(3)函数格式
所需头文件#include
函数原型int sem_init(sem_t *sem,int pshared,unsigned int value)
函数传入值
sem:信号量
pshared:决定信号量能否在几个进程间共享。由于目前Linux还没有实现进程间共享信
号量,所以这个值只能够取0
value:信号量初始化值
函数返回值
成功:0
出错:-1
sem_wait等函数的语法要点
所需头文件#include
函数原型
int sem_wait(sem_t *sem)
int sem_trywait(sem_t *sem)
int sem_post(sem_t *sem)
int sem_getvalue(sem_t *sem)
int sem_destroy(sem_t *sem)
函数传入值sem:信号量
函数返回值
成功:0
出错:-1
/*sem_mutex.c*/
#include
#include
#include
#include
#include
#include
#include
int lock_var;
time_t end_time;
sem_t sem;
void pthread1(void *arg);
void pthread2(void *arg);
int main(int argc, char *argv[])
{
pthread_t id1,id2;
pthread_t mon_th_id;
int ret;
end_time = time(NULL)+30;
/*初始化信号量为1*/
ret=sem_init(&sem,0,1);
if(ret!=0)
{
perror("sem_init");
}
/*创建两个线程*/
ret=pthread_create(&id1,NULL,(void *)pthread1, NULL);
if(ret!=0)
perror("pthread cread1");
ret=pthread_create(&id2,NULL,(void *)pthread2, NULL);
if(ret!=0)
perror("pthread cread2");
pthread_join(id1,NULL);
pthread_join(id2,NULL);
exit(0);
}
void pthread1(void *arg)
{
int i;
while(time(NULL) < end_time){
/*信号量减一,P操作*/
sem_wait(&sem);
for(i=0;i<2;i++){
sleep(1);
lock_var++;
printf("lock_var=%d\n",lock_var);
}
printf("pthread1:lock_var=%d\n",lock_var);
/*信号量加一,V操作*/
sem_post(&sem);
sleep(1);
}
}
void pthread2(void *arg)
{
int nolock=0;
int ret;
while(time(NULL) < end_time){
/*信号量减一,P操作*/
sem_wait(&sem);
printf("pthread2:pthread1 got lock;lock_var=%d\n",lock_var);
/*信号量加一,V操作*/
sem_post(&sem);
sleep(3);
}
}
阅读(2556) | 评论(1) | 转发(0) |