操作系统并发性(四) 信号量

信号量的含义

信号量是一个有整数值的对象,它的语义针对某个特定的资源,它的值是可用的资源个数的抽象。

当值大于零时,值表示可用的资源个数。

当值小于零时,值表示正在等待的线程个数。

当值等于零时,表示没有线程等待,但是自己无法使用该资源。

信号量的底层是利用锁与条件变量实现的,而锁与条件变量的实现又是利用到了底层硬件的支持,包括同步原语,等待队列,休眠机制等

操作系统并发性(二):锁

操作系统并发性(三):条件变量

信号量的API

信号量最大的好处就是代码量小,尤其是比条件变量小的多,使用极其方便。

//头文件
#include <semaphore.h>
//数据结构
sem_t s;
//初始化,第三个参数表明s的初始值,第二个参数一般设置为0,
//表示信号量是多个线程共享的。
sem_init(&s, 0, 1);
//使用
sem_post(&s);
sem_wait(&s);

sem_wait执行步骤:

  1. 将信号量的值减1
  2. 如果此时信号量的值大于等于0,跳出,否则陷入休眠

sem_post执行步骤:

  1. 将信号量的值加1
  2. 如果有其他线程休眠,唤醒一个线程

用信号量实现锁

sem_t s;
sem_init(&s, 0, 1);

sem_wait(&s);
//临界区代码
sem_post(&s);

使用一目了然,注意这里信号量的初值赋为1。表示第一个线程可以进入临界区。

用信号量实现条件变量

以父线程等待子线程执行完毕为例。

sem_t s;

void* thr_son(void*)
{
	printf("son begin\n");
	printf("son end\n");
	sem_post(&s);
	return NULL;
}
	

int main()
{
	sem_init(&s, 0, 0);
	printf("father begin\n");
	pthread_t son;
	pthread_create(&son, NULL, thr_son, NULL);
	sem_wait(&s);
	printf("father end\n");
}

使用锁与条件变量实现信号量

这里我们用锁与条件变量实现一个自己的信号量 zem_t。

依次实现信号量的三个API,并用它实现父线程等待子线程的功能。

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct zem_t{
    int value;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
}zem_t;

zem_t z;

void zem_init(zem_t* zem_p, int value)
{
    zem_p->value = value;
    pthread_mutex_init(&zem_p->mutex, NULL);
    pthread_cond_init(&zem_p->cond, NULL);
}

void zem_post(zem_t* zem_p)
{
    pthread_mutex_lock(&zem_p->mutex);
    zem_p->value++;
    pthread_cond_signal(&zem_p->cond);
    pthread_mutex_unlock(&zem_p->mutex);
}

void zem_wait(zem_t* zem_p)
{
    pthread_mutex_lock(&zem_p->mutex);
    zem_p->value--;
    while (zem_p->value < 0)
        pthread_cond_wait(&zem_p->cond, &zem_p->mutex);
    pthread_mutex_unlock(&zem_p->mutex);
}
void* thr_son(void*)
{
	printf("son begin\n");
	printf("son end\n");
	zem_post(&z);
	return NULL;
}
int main()
{
	zem_init(&z, 0);
	printf("father begin\n");
	pthread_t son;
	pthread_create(&son, NULL, thr_son, NULL);
	zem_wait(&z);
	printf("father end\n");

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值