信号量

本文介绍了信号量的概念,包括临界资源、临界区和PV操作,并通过实例展示了如何使用二值信号量实现打印机的顺序打印。还探讨了如何使用三个信号量实现进程A、B、C的循环有序打印。最后,给出了各进程的打印函数示例,强调了信号量在进程同步中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习信号量先要明白几个专业术语:
临界资源:同一时刻只允许一个进程访问的资源。
临界区:访问临界资源的代码段。
作用:同步进程

信号量:特殊变量
取正数值:二值信号量0,1
技术信号量:如信号量值为3

PV操作:

P操作:有可能阻塞,对信号量的值进行减一代表获取资源。当信号量值为0时就会阻塞。
V操作:对信号量进行加一代表释放资源。

就比方下面这个打印机,我们要求A打印完了,才能打印B,表现形式就是AA或者BB,不能出现AB,BA这种情况。
在这里插入图片描述
想一想其实只要定义一个初值为1的二值信号量,代表打印机的可用资源为1,要是其中某个程序对信号量进行p操作另外一个程序不就阻塞住,只能等待V操作之后将资源释放,这个程序才能进行P操作去获取这个资源。

A的打印程序!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include “sem.h”//写好的信号量的库

int main()
{

sem_init();//定义一个信号量初始值为1
int i = 0;
for(; i < 5; i++ )
{
	sem_p();//信号量-1变成0
	printf("A");
	fflush(stdout);
	int n = rand() % 3;
	sleep(n);
	printf("A");
	fflush(stdout);
	sem_v();//信号量+1变成1

	n = rand() % 3;
	sleep(n);
}

sleep(10);
sem_destroy();

}

B的打印程序!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include “sem.h”

int main()
{
sem_init();//如果A里面先把信号量定义了,那这里就是获取那个信号量,
//反之就是A获取B里面的信号量
int i = 0;
for(; i < 5; i++ )
{
sem_p();//信号量-1==0
printf(“B”);
fflush(stdout);
int n = rand() % 3;
sleep(n);
printf(“B”);
fflush(stdout);
sem_v();//信号量+1=1

	n = rand() % 3;
	sleep(n);
}

}

成果:其实还是有很多问题的,比如没有错误处理,后期的学习会加上的。
在这里插入图片描述现在我们来写这样的一个程序:
写三个不同的进程,分别打印A B C使得打印出来的字母是顺序ABC,进行循环打印。

**思路:**打印A的时候B,C阻塞,打印完A,B开始打印,B打印完,C开始打印,C打印完,A又重新开始

具体的·方法就是下图

在这里插入图片描述
A的打印函数:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include “sem.h”

int main()
{
int arr[3]={1,0,0};//定义3个信号量初始值为1 0 0,或者说获取别人已经定义好的信号量
sem_init(arr,3);//三个信号量分别为S0 S1 S2

int i=0;
for(;i<5;i++)
{
    sem_p(0);//S0-1=0
    printf("A");
    fflush(stdout);
    sem_v(1);//S1+1=1

}
exit(0);

}

B的打印函数:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include “sem.h”

int main()
{
int arr[3]={1,0,0};//定义3个信号量初始值为1 0 0,或者说获取别人已经定义好的信号量
sem_init(arr,3);//三个信号量分别为S0 S1 S2

int i=0;
for(;i<5;i++)
{
    sem_p(1);//S1-1=0
    printf("B");
    fflush(stdout);
    sem_v(2);//S2+1=1
}

exit(0);

}

C的打印函数:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include “sem.h”

int main()
{
int arr[3]={1,0,0};//定义3个信号量初始值为1 0 0,或者说获取别人已经定义好的信号量
sem_init(arr,3);//三个信号量分别为S0 S1 S2

int i=0;
for(;i<5;i++)
{
    sem_p(2);//S2-0=0
    printf("C");
    fflush(stdout);
    sem_v(0);//S0+1=1
}

sem_destroy();//删除信号量
exit(0);

}

结果:在这里插入图片描述
信号量这里先说这么多艹

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值