linux 线程中的信号

信号量

信号量,是相对折中的一种处理方式,既能保证同步,数据不混乱,又能提高线程并发。
由于互斥锁的粒度比较大,如果我们希望在多个线程间对某- -对象的部分数据进行共享,使用互斥锁是
没有办法实现的,只能将整个数据对象锁住。这样虽然达到了多线程操作共享数据时保证数据正确性的
目的,却无形中导致线程的并发性下降。线程从并行执行,变成了串行执行。与直接使用单进程无异。

主要函数

sem. init 函数
sem_ destroy函数
sem. _wait 函数
sem_ trywait 函数
sem. timedwait函数
sem. post函数
以上6个函数的返回值都是:成功返回0,失败返回-1,同时设置errng。 (注意, 它们没有pthread前缀)
sem_ .t类型,本质仍是结构体。但应用期间可简单看作为整数,忽略实现细节(类似于使用文件描述符)。
sem_ .tsem;规定信号量sem不能<0
头文件<semaphore.h>

信号量基本操作

sem_wait:

1.信号量大于0,则信号量-- (类比pthread_mutex_lock)

2.信号量等于0时,再次调用会造成线程阻塞。

对应

sem_post:

将信号量++,同时唤醒阻塞在信号量上的线程(类比pthread_mutex_unlock)

但是由于sem的实现对用户隐藏,所以所谓的++,--操作只能通过函数来实现,而不能直接++,,符号信号量的初值,决定了占用信号量线程的个数。

sem destroy函数

销毁信号量

int sen_destroy(sem_t *sem);

sem_ wait函数
信号量减减操作(类似加锁)
int sem_ wait(sen. t *sem);


sem_ post函数
信号量加加操作(类似解锁)
int sem_ post(sen _t *sem);
例程:利用信号操作实现生产消费者模型

#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#define NUM 100

int queue[NUM];
sem_t blank_number,product_number,product_number2;

void *producer(void *arg)
{
        while(1)
        {
                sem_wait(&blank_number);
                sem_post(&product_number);
                i=(i+2)%NUM;
                sleep(2);
        }
}
void *producer02(void *arg)
{
        sleep(2);
        {
                sem_wait(&blank_number);
                queue[i]=rand()%1000+2;
                sem_post(&product_number2);
                i=(i+1)%NUM;
                sleep(2);
        }
}
void *consumer(void *arg)
{
        int i=0;
        {
                sleep(1);
                sem_wait(&product_number2);
                queue[i]=0;
                sem_post(&blank_number);
                i=(i+1)%NUM;
        }
}
//void *consumer02(void *arg)
//{
//      int i=1;
//      sleep(1);
//      while(1)
//      {
//              sleep(2);
//              sem_wait(&product_number);
//              queue[i]=0;
//              sem_post(&blank_number);
//              i=(i+2)%NUM;
//      }
//}
int main(int argc,char *argv[])
{
        pthread_t pid[2],cid[2];
        sem_init(&blank_number,0,NUM);
        sem_init(&product_number,0,0);
        sem_init(&product_number2,0,0);
        pthread_create(&pid[0],NULL,producer,NULL);
        pthread_create(&pid[1],NULL,producer02,NULL);
        pthread_create(&cid[0],NULL,consumer,NULL);
//      pthread_create(&cid[1],NULL,consumer02,NULL);

        pthread_join(pid[0],NULL);
        pthread_join(pid[1],NULL);
        pthread_join(cid[0],NULL);
//      pthread_join(cid[1],NULL);

        sem_destroy(&blank_number);
        sem_destroy(&product_number);
        sem_destroy(&product_number2);
        return 0;
}

此程序为两个生产者,一个消费者

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值