文章目录
- 前言
- 1 什么是信号量
-
- 1.1 信号量API函数
- 2、信号量实验
-
- 2.1 实验目的
- 2.2函数源码
- 2.3 运行结果图
前言
本文记录rk3568开发板的信号量实验
1 什么是信号量
信号量是同步的一种方式,常常用于控制对共享资源的访问。
举个例子:停车场的停车位有100个,这100个停车位就是共享资源,信号量的值最多等于100。当有车进停车场,信号量加1;当有车出去停车场,信号量减1
信号量特点:
• 信号量可以使线程进入休眠状态,高CPU使用效率,不需要一直占用CPU资源。提高CPU使用效率,不需要一直占用CPU资源。
• 不能用于中断,因为信号量会引起休眠,中断不能休眠。
• 适合用于占用资源比较久的场合,如果共享资源的持有时间比较短,那么不适合使用信号量了,因为频繁的休眠,切换切换线程引起的开销要远大于信号量带来的那点优势。
两种用法:
①信号量初始值大于1,则不能用于互斥访问。因为它允许多个线程同时访问共享资源。
②如果信号量初始值为1,那么可以用于互斥访问共享资源。该信号量就是要给二值信号量。
1.1 信号量API函数
Linux内核使用信号量结构体
struct semaphore {
raw_spinlock_t lock;
unsigned int count;
struct list_head wait_list;
};
信号量的用法
2、信号量实验
2.1 实验目的
为了能让应用程序不用一直死等某个共享资源,做此实验验证信号量能让第二个线程进入睡眠状态,且获取信号量资源后,第二个线程自动唤醒执行。
思路:
- init初始化信号量为1
- open函数限制信号量,如果成功获取信号量,则信号量减1。若无法获取信号量,则退出
- release函数会让信号量加1。
说明:
代码如下(示例):
int down_interruptible(struct semaphore *sem)
{
unsigned long flags;
int result = 0;
spin_lock_irqsave(&sem->lock,flags);
if (likely(sem->count> 0))
sem->count--;
else
result =__down_interruptible(sem);
spin_unlock_irqrestore(&sem->lock,flags);
return result;
}
函数分析:若成功获取信号量,则信号量值减1,且函数返回值等于0;若获取信号量失败,则函数返回值返回非0
此函数可以被信号量打断正在休眠的线程
2.2函数源码
驱动程序semaphore.c
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define GPIOLED_CNT 1 /* 设备号个数 */
#define GPIOLED_NAME "gpioled" /* 名字 */
#define LEDOFF 0 /* 关灯 */
#define LEDON 1 /* 开灯 */
struct led_dev
{
dev_t devid; /* 设备号 */
struct cdev cdev; /* cdev */
struct class *class; /* 类 */
struct device *device; /* 设备 */
int major; /* 主设备号 */
int minor; /* 次设备号 */
struct device_node *nd; /* 设备节点 */
int led_gpio; /* led所使用的GPIO编号 */
int dev_stats; /* 设备使用状态,0,设备