栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

信号量的含义

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

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

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

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

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

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

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

信号量的API

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

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

sem_wait执行步骤:

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

sem_post执行步骤:

    将信号量的值加1如果有其他线程休眠,唤醒一个线程
用信号量实现锁
sem_t s;
sem_init(&s, 0, 1);

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

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

用信号量实现条件变量

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

sem_t s;

void* thr_son(void*)
{
	printf("son beginn");
	printf("son endn");
	sem_post(&s);
	return NULL;
}
	

int main()
{
	sem_init(&s, 0, 0);
	printf("father beginn");
	pthread_t son;
	pthread_create(&son, NULL, thr_son, NULL);
	sem_wait(&s);
	printf("father endn");
}
使用锁与条件变量实现信号量

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

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

#include 
#include 
#include 

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 beginn");
	printf("son endn");
	zem_post(&z);
	return NULL;
}
int main()
{
	zem_init(&z, 0);
	printf("father beginn");
	pthread_t son;
	pthread_create(&son, NULL, thr_son, NULL);
	zem_wait(&z);
	printf("father endn");

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/779549.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号