Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3231673
  • 博文数量: 346
  • 博客积分: 10189
  • 博客等级: 上将
  • 技术积分: 3125
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-05 19:46
文章分类

全部博文(346)

文章存档

2013年(35)

2011年(35)

2010年(76)

2009年(48)

2008年(152)

分类: C/C++

2008-09-03 10:15:09

使用POSIX 1003.1b信号量,有别于SystemV(ipc, semctl, semop)的信号量操作。

信号量是为线程间共享的资源计数。信号量的基础操作是:原子性的增加计数,和等待直到计数器非空并且原子性的减少计数。

1)       API

1.13 #include

信号量初始化

int sem_init(sem_t *sem, int pshared, unsigned int value);

返回: 如果成功0, 失败设置 Exxx error

 

初始化sem指针指向的信号量,此信号量的计数为value。第2个参数指明此信号量是本地本进程使用(0)还是进程间可以使用(非0)。Linux线程当前不支持进程间使用。因此如果pshared是非0,将返回ENOSYS错误。

 

 

1.14 #include

信号量等待函数。相当于P原语

int sem_wait(sem_t * sem);

返回: 如果成功0, 失败设置 Exxx error

 

挂起调用此函数的线程直到sem指针指向的信号量不为0。此函数将原子性的减少信号量。

 

 

 

1.15 #include

sem_wait的非阻塞版

int sem_trywait(sem_t * sem);

返回: 如果成功0, 失败设置 Exxx error

 

此函数是sem_wait的非阻塞版。如果sem指向的信号量是非0值,那么此计数将原子性的减少并且此函数立即返回0。如果信号量是0,那么sem_trywait函数立即返回错误EAGAIN

 

 

1.16 #include

信号量释放操作。相当于 原语V

int sem_post(sem_t * sem);

返回: 如果成功0, 失败设置 Exxx error

 

原子性的增加由sem指向的信号量计数。这个函数不会被阻塞。

 

 

1.17 #include

获得信号量

int sem_getvalue(sem_t * sem, int * sval);

返回: 如果成功0, 失败设置 Exxx error

 

获得sem指向的信号量的指到sval中。

 

 

1.18 #include

信号量销毁函数

int sem_destroy(sem_t * sem);

返回: 如果成功0, 失败设置 Exxx error

 

销毁一个信号量对象,释放他可能拥有的资源。在调用sem_destroy函数后没有线程可以再等待此信号量。在Linux线程实现中,没有资源于信号量相关联,因此sem_destroy事实上除了检查没有线程等待此信号量外什么也没作。

 

2)       Example

/* File sem.c */
#include

#include
<semaphore.h>
#include

#define MAXSTACK 100
int stack[MAXSTACK][2];
int size=0;
sem_t sem;
/*
从文件1.dat读取数据,每读一次,信号量加一*/
void ReadData1(void){
    FILE *fp =
fopen("1.dat","r");
    while(!feof(fp))
{
       
fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);
        
sem_post(&sem);
       
++size;
   
}
   
fclose(fp);
}
/*
从文件2.dat读取数据
*/
void ReadData2(void){
   
FILE *fp=fopen("2.dat","r");
    while(!feof(fp))
{
       
fscanf(fp,"%d %d",&stack[size][0],&stack[size][1]);
       
sem_post(&sem);
       
++size;
   
}
   
fclose(fp);
}
/*
阻塞等待缓冲区有数据,读取数据后,释放空间,继续等待
*/
void HandleData1(void){
   
while(1){
       
sem_wait(&sem);
       
printf("Plus:%d+%d=%d\n",stack[size][0],stack[size][1],
       
stack[size][0]+stack[size][1]);
       
--size;
   
}
}

void HandleData2(void){
   
while(1){
       
sem_wait(&sem);
       
printf("Multiply:%d*%d=%d\n",stack[size][0],stack[size][1],
       
stack[size][0]*stack[size][1]);
       
--size;
   
}
}
int main(void){
   
pthread_t t1,t2,t3,t4;
   
sem_init(&sem,0,0);
   
pthread_create(&t1,NULL,(void *)HandleData1,NULL);
   
pthread_create(&t2,NULL,(void *)HandleData2,NULL);
   
pthread_create(&t3,NULL,(void *)ReadData1,NULL);
   
pthread_create(&t4,NULL,(void *)ReadData2,NULL);
    /*
防止程序过早退出,让它在此无限期等待
*/
   
pthread_join(t1,NULL);
}

 

阅读(1953) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~