函数语法快速参考(并发与竞态、高级字符驱动程序操作)

并发与竞态

#include <asm/semaphore.h>
定义信号量及其操作的包含文件

DECLARE_MUTEX(name);
DECLARE_MUTEX_LOCKED(name);
用于声明和初始化用在互斥模式中的信号量的两个宏

void init_MUTEX(struct semaphore *sem);
void init_MUTEX_LOCKED(struct semaphore *sem);
这两个函数可以在运行时初始化信号量

void down(struct semaphore *sem); 锁定信号量
int down_interruptible(struct semaphore *sem); 锁定信号量
int down_trylock(struct semaphore *sem); 锁定信号量
void up(struct semaphore *sem); 解锁信号量
如果必要,down会将调用进程置于不可中断的休眠状态;相反down_interruptible可以被信号中断。down_trylock不会休眠,并且会在信号量不可用时立即返回。锁定信号量的代码最后必须用up解锁该信号量

struct rw_semaphore;
init_rwsem(struct rw_semaphore *sem);
信号量的读取者/写入者版本以及用来初始化这种信号量的函数。

void down_read(struct rw_semaphore *sem);
int down_read_trylock(struct rw_semaphore *sem);
void up_read(struct rw_semaphore *sem);
获取并释放对读取者/写入者信号量的读取访问函数

void down_write(struct rw_semaphore *sem);
int down_write_trylock(struct rw_semaphore *sem);
void up_write(struct rw_semaphore *sem);
void downgrade_write(struct rw_semaphore *sem);
对读取者/写入者信号量的写入访问进行管理的函数

#include <linux/completion.h>
DECLARE_COMPLETION(name);
init_completion(struct completion *c);
INIT_COMPLETION(struct completion c);
描述Linux的completion机制的包含文件,以及用于初始化completion的常用方法。INIT_COMPLETION只能用于对已使用过的completion的重新初始化。

void wait_for_completion(struct completion *c);
等待一个completion事件的发生

void complete(struct completion *c);
void complete_all(struct completion *c);
发出completion时间信号。complete最多只能唤醒一个等待的线程,而complete_all会唤醒所有的等待者。

void complete_and_exit(struct completion *c, long retval);
通过调用complete并调用当前线程的exit函数而发出的completion时间信号。

#include <linux/spinlock.h>
spinlock_t lock = SPIN_LOCK_UNLOCKED;
spin_lock_init(spinlock_t *lock);
定义自旋锁接口的包含文件,以及初始化自旋锁的两种方式

void spin_lock(spinlock_t *lock);
void spin_lock_irqsave(spinlock_t *lock, unsigned long flags); 获取自旋锁之前禁止中断,而先前的中断状态保存在flags中
void spin_lock_irq(spinlock_t *lock); 如果我们能够确保在释放自旋锁时应该启用中断,那么使用该函数,无需跟踪标志
void spin_lock_bh(spinlock_t *lock); 获得锁之前禁止软件中断,但是会让硬件中断保持打开
锁定自旋锁的不同方式

int spin_trylock(spinlock_t *lock);
int spin_trylock_bh(spinlock_t *lock);
上述函数的非自旋版本。这些函数在无法获得自旋锁的时候返回零,否则返回非零。

void spin_unlock(spinlock_t *lock);
void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);
void spin_unlock_irq(spinlock_t *lock);
void spin_unlock_bh(spinlock_t *lock);
释放自旋锁的相应途径,严格对应获取自旋锁的函数

#include <asm/atomic.h>
atomic_t v = ATOMIC_INIT(value); 编译时初始化为value
void atomic_set(atomic_t *v, int i); 将原子变量v的值设为整数值i
int atomic_read(atomic_t *v); 返回v的当前值
void atomic_add(int i, atomic_t *v); 将i累加到v所指向的原子变量
void atomic_sub(int i, atomic_t *v); 从*v中减去i
void atomic_inc(atomic_t *v); 增加一个原子变量
void atomic_dec(atomic_t *v); 减少一个原子变量

int atomic_inc_and_test(atomic_t *v);
int atomic_dec_and_test(atomic_t *v);
int atomic_sub_and_test(int i, atomic_t *v);
执行特定操作并测试结果;如果在操作结束之后,原子值为0,则返回值为true;否则返回false

int atomic_add_negative(int i, atomic_t *v); 将整数变量i累加到v,返回值在结果为负的时候为true,否则为false
int atomic_add_return(int i, atomic_t *v);
int atomic_sub_return(int i, atomic_t *v);
int atomic_inc_return(atomic_t *v);
int atomic_dec_return(atomic_t *v);
类似于atomic_add及其变种,例外之处在于这些函数会将新的值返回给调用者。
对atomic_t变量的访问必须通过上述函数

#include <asm/bitops.h>
void set_bit(nr, void *addr); 设置addr指向的数据项的第nr位
void clear_bit(nr, void *addr); 清除addr指向的数据项的第nr位,其原语和set_bit相反
void change_bit(nr, void *addr);
test_bit(nr, void *addr);
int test_and_set_bit(nr, void *addr);
int test_and_clear_bit(nr, void *addr);
int test_and_change_bit(nr, void *addr);
对位值的原子访问,它们可用于标志或锁变量。使用这些函数可避免因为对相应位的并发访问而导致的任何竞态。
 

高级字符驱动程序操作

#include <linux/ioctl.h>
声明用于定义ioctl命令的所有的宏。现在包含在<linux/fs.h>中。
_IOC_NRBITS
_IOC_TYPEBITS
_IOC_SIZEBITS
_IOC_DIRBITS
ioctl命令的不同位字段的可用位数。

_IOC_NONE
_IOC_READ
_IOC_WRITE
“方向”位段的可能值。

_IOC(dir,type,nr,size)
_IO(type,nr)
_IOR(type,nr,size)
_IOW(type,nr,size)
_IOWR(type,nr,size)
用于生成ioctl命令的宏。

_IOC_DIR(nr) 提取方向
_IOC_TYPE(nr) 提取幻数
_IOC_NR(nr) 提取序数
_IOC_SIZE(nr) 提取数据大小
用于解码ioctl命令的宏。

#include <asm/uaccess.h>
int access_ok(int type, const void *addr, unsigned long size);
用于验证指向用户空间的指针是否可用。如果允许访问,access_ok返回非零值。

VERIFY_READ
VERIFY_WRITE
access_ok 中 type 参数可取的值.。VERIFY_WRITE 是 VERIFY_READ 的超集。

#include <asm/uaccess.h>
int put_user(datum,ptr);
int get_user(local,ptr);
int __put_user(datum,ptr);
int __get_user(local,ptr);
用于向(或从)用户空间保存(或获取)单个数据项的宏。传送的字节数目由sizeof(*ptr)决定。

#include <linux/capability.h>
定义有各种CAP_符号,用于描述用户空间经常可能拥有的权能操作。

int capable(int capability);
如果进程具有指定的权能,返回非0值。

#include <linux/wait.h>
typedef struct { /* ... */ } wait_queue_head_t;
void init_waitqueue_head(wait_queue_head_t *queue);
DECLARE_WAIT_QUEUE_HEAD(queue);
预先定义的等待队列类型。wait_queue_head_t类型必须显示的初始化,初始化方式可以在运行的时候调用init_waitqueue_head,或者在编译的时候用DECLARE_WAIT_QUEUE_HEAD。

void wait_event(wait_queue_head_t q, int condition);
int wait_event_interruptible(wait_queue_head_t q, int condition);
int wait_event_timeout(wait_queue_head_t q, int condition, int time);
int wait_event_interruptible_timeout(wait_queue_head_t q, int condition,int time);
使进程在指定的队列上休眠,直到给定的condition值为真。

void wake_up(struct wait_queue **q);
void wake_up_interruptible(struct wait_queue **q);
void wake_up_nr(struct wait_queue **q, int nr);
void wake_up_interruptible_nr(struct wait_queue **q, int nr);
void wake_up_all(struct wait_queue **q);
void wake_up_interruptible_all(struct wait_queue **q);
void wake_up_interruptible_sync(struct wait_queue **q);
唤醒休眠在队列q上的进程。_interruptible形式的函数只能唤醒可中断的进程。通常,只会唤醒一个独占等待进程,但其行为可通过_nr或_all形式改变。_sync版本的唤醒函数在返回钱不会重新调度CPU。

#include <linux/sched.h>
set_current_state(int state);
设置当前进程的执行状态。TASK_RUNNING表示准备运行,而休眠状态是TASK_INTERRUPTIBLE 和 TASK_UNINTERRUPTIBLE。

void schedule(void);
从运行队列中选择一个可执行的进程。选定的进程可以是current或另一个不同的进程。

typedef struct { /* ... */ } wait_queue_t;
init_waitqueue_entry(wait_queue_t *entry, struct task_struct *task);
wait_queue_t类型用来将某个进程放置到一个等待队列上。

void prepare_to_wait(wait_queue_head_t *queue, wait_queue_t *wait, int state);
void prepare_to_wait_exclusive(wait_queue_head_t *queue, wait_queue_t *wait, int state);
void finish_wait(wait_queue_head_t *queue, wait_queue_t *wait);
可用于手工休眠代码的辅助函数。

#include <linux/poll.h>
void poll_wait(struct file *filp, wait_queue_head_t *q, poll_table *p);
将当前进程置于某个等待队列但不立即调度。该函数主要用于设备驱动程序的poll方法。

int fasync_helper(struct inode *inode, struct file *filp, int mode, struct fasync_struct **fa);
用来实现fasync设备方法的辅助函数。mode参数取传入该方法的同一值,而fa指向设备专有的fasync_struct *。

void kill_fasync(struct fasync_struct *fa, int sig, int band);
如果驱动程序支持异步通知,则这个函数可以用来发送一个信号给注册在fa中的进程。

int nonseekable_open(struct inode *inode, struct file *filp);
loff_t no_llseek(struct file *file, loff_t offset, int whence);
任何不支持定位的设备都应该在其open方法中调用nonseekable_open。这类设备还应该在其llseek方法中使用no_llseek。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值