信号量与自旋锁
来源:互联网 发布:cad网络插座图标 编辑:程序博客网 时间:2024/05/22 00:22
1. 定义:
头文件: <asm/semaphore.h>
数据类型: struct semaphore
直接创建:
void sema_init(struct semaphore *sem, int val); /* 其中val是信号量的初始值 */
辅助宏:
DECLARE_MUTEX(name); /* 把一个称为name的信号量变量初始化为1 */
DECLARE_MUTEX_LOCKED(name); /* 把一个称为name的信号量变量初始化为0 */
动态分配:
/* 用于运行时的初始化 */
void init_MUTEX(struct semaphore *sem);
void init_MUTEX_LOCKED(struct semaphore *sem);
在Linux世界中, P函数被称为down, 指的是该函数减小了信号量的值, 它也许会将调用者置于休眠状态, 然后等待信号量变得可用, 之后再授予调用者对被保护资源的访问权限. down函数有三个版本:
/* 减小信号量的值, 并在必要时一直等待 */
void down(struct semaphore *sem);
/* 可中断版本, 常用 */
void down_interruptible(struct semephore *sem);
作为通常规则, 我们不应该使用非中断版本. 使用该函数, 如果操作被中断, 该函数会返回非0值, 而调用者不会拥有该信号量. 因此对该函数的正确使用需要始终检查返回值, 并做出相应的响应.
/* 永远不会休眠, 如信号量在调用时不可获得, 立即返回非0值 */
void down_trylock(struct semaphore *sem);
当一个线程成功调用down函数的某个版本之后, 就称为该线程拥有了该信号量, 可以访问被该信号量保护的临界区. 当互斥操作完成后, 必须释放该信号量.
Linux的V函数是up:
/* 调用up之后, 调用者不再拥有该信号量 */
void up(struct semaphore *sem);
2. 举例:
我们拥有一个共享数据结构:
struct st_data
{
char name[32];
char data[128];
int data_len;
};
这个数据结构被多个进程同时访问.为了避免这些进程在访问该结构时产生竞态, 我们在该结构的底部为其加上信号量:
struct st_data
{
char name[32]; /* name */
char data[128]; /* data */
int data_len; /* data length */
struct semaphore sem; /* semaphore */
};
信号量在使用前必须进行初始化, 而且是在共享数据其他部分可用前初始化. 因此, 我们在其他数据赋值之前调用init_MUTEX, 否则会建立一个竞态, 即在信号量准备好之前, 有代码可能会访问它们.
st_data data;
init_MUTEX(&data->sem);
setup_data(&data); /* 初始化数据 */
...
...
接下来, 我们必须仔细检查代码, 确保在不拥有该信号量的时候不会访问data数据结构. 例如, 在data_write的开始处加入:
if (down_interruptible(&data->sem))
return -ERESTARTSYS;
这是检查down_interruptible的返回值, 如果返回非0值, 说明操作被中断. 这种情况下, 通常要做的工作是返回-ERESTARTSYS. 在得到这个返回值后, 内核会从头重新启动该调用, 或者将该错误返回给用户.如果我们返回-ERESTARTSYS, 则必须首先撤销已经做出的修改, 这样, 系统调用才可正确重试. 如果无法撤销这些操作, 则应该返回-EINTR, 表明中断.不管data_write能否完成其他工作, 它都必须释放信号量:
out:
up(&data->sem);
return retval;
在data_write中有几个地方可能会产生错误, 包括内存分配失败等. 在这些情况下, 代码会执行goto out, 确保正确的完成信号量的释放工作.
- 自旋锁与信号量
- 自旋锁与信号量
- 信号量与自旋锁
- 信号量与自旋锁
- 自旋锁与信号量
- 信号量与自旋锁
- 信号量与自旋锁
- 信号量与自旋锁
- 信号量与自旋锁
- 自旋锁与信号量
- 自旋锁与信号量
- 信号量与自旋锁
- 信号量与自旋锁(5): 自旋锁
- 自旋锁与信号量比较
- linux信号量与自旋锁
- 自旋锁与信号量(转载)
- 自旋锁与信号量(转载)
- Linux自旋锁与信号量
- SQL语言基础--数据插入修改删除
- 【sgu】107 解题报告
- 使用platformRequest()自动更新MIDlet套件
- linux工作队列
- ptrace manpage 中文翻译下
- 信号量与自旋锁
- Linux工作队列的使用
- 防刷新倒计时
- 101到200的质数(j=1和j=2)
- Tip - Silverlight: TextBox的TextChanged事件不更新Data Binding源的解决办法
- VMS和Windows NT的首席设计师大卫·卡特勒(David Cutler)
- 教你如何复制别人的QQ空间为自己用
- 发票校验部分增强
- hdu 1087 Super Jumping! Jumping! Jumping!(动态规划)