信号量

信号量


信号量本质上是一个的整数计数器, 它被用来控制对公共资源的访问. 当公共资源增加时, 调用 函数sem_post()增加信号量. 只有当信号量值大于0时, 才能使用公共资源, 使用后函数sem_wait()减少信号量. 函数sem_trywait() 和函数 pthread_mutex_trylock() 起同样的作用, 它是函数sem_wait()的非阻塞版本. 
它们在头文件/usr/include/semaphore.h中.
信号量的数据类型的结构是sem_t, 它本质是一个长整形的数. 函数sem_init()用来初始化一个信号量. 它的原型为: extern int sem_init __P(( sem_t * __sem, int __pshared, unsigned int __value));
sem为指向信号结构的一个指针; pshared不为0时此信号在进程间共享, 否则只能为当前进程所有线程共享; value给出了信号量的初始值.
函数sem_post( sem_t * sem)用来增加信号量的值. 当有线程阻塞在这个信号量上时, 调用这个函数会使其中的一个线程不再阻塞, 选择机制同样是线程的调度策略决定的.
函数sem_wait( sem_t * sem)被用来阻塞当前线程直到信号量sem的值大于0, 解除阻塞后将sem的值减一, 表明公共资源已经使用后减少.
函数sem_trywait( sem_t * sem)是函数sem_wait的非阻塞版本, 它直接将信号量sem的值减一.
函数sem_destroy(sem_t * sem)用来释放信号量sem.
来看一个例子, 一共有4个线程, 其中两个线程负责从文件读取数据到公共缓冲区, 另两个线程从缓冲区读取数据作不同的处理( 加和乘运算)
/*file sem.c */
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>


#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;
    }
}


/*阻塞等待缓冲区有数据, 读取数据后, 释放空间,继续等待*/
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);


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值