概述
current
宏是Linux内核中最重要的宏之一,用于获取当前正在运行进程的进程描述符(task_struct结构体指针)。它让内核代码能够快速访问当前进程的相关信息。
定义位置
// 主要定义在以下头文件中:
#include <asm/current.h>
#include <linux/sched.h>
架构相关实现
x86架构实现
在x86架构中,current
宏的实现方式:
// arch/x86/include/asm/current.h
DECLARE_PER_CPU(struct task_struct *, current_task);
static __always_inline struct task_struct *get_current(void)
{
return this_cpu_read_stable(current_task);
}
#define current get_current()
ARM架构实现
// arch/arm/include/asm/current.h
static inline struct task_struct *get_current(void)
{
struct task_struct *cur;
__asm__("mov %0, sp\n"
"bic %0, %0, %1"
: "=r" (cur)
: "I" (THREAD_SIZE - 1));
return ((struct thread_info *)cur)->task;
}
#define current get_current()
实现原理
1. Per-CPU变量方式(x86)
- 每个CPU核心维护一个
current_task
变量 - 指向当前CPU上正在执行的进程的task_struct
- 进程切换时更新此变量
2. 栈指针计算方式(ARM等)
- 利用内核栈的特殊布局
- 通过当前栈指针计算thread_info位置
- 从thread_info中获取task_struct指针
使用示例
基本使用
#include <linux/sched.h>
// 获取当前进程PID
pid_t pid = current->pid;
// 获取当前进程名称
char *comm = current->comm;
// 检查当前进程权限
if (capable(CAP_SYS_ADMIN)) {
// 执行需要管理员权限的操作
}
// 访问进程内存描述符
struct mm_struct *mm = current->mm;
在系统调用中使用
SYSCALL_DEFINE1(my_syscall, int, param)
{
// 获取当前进程信息
struct task_struct *task = current;
printk(KERN_INFO "Process %s (PID: %d) called my_syscall\n",
task->comm, task->pid);
// 检查进程状态
if (task->state != TASK_RUNNING) {
return -EINVAL;
}
return 0;
}
常用访问模式
进程基本信息
// 进程ID相关
current->pid // 进程ID
current->tgid // 线程组ID(主线程PID)
current->ppid // 父进程ID
// 进程名称和状态
current->comm // 进程名称(最多16字符)
current->state // 进程状态
// 用户和组ID
current->cred->uid // 实际用户ID
current->cred->euid // 有效用户ID
current->cred->gid // 实际组ID
内存管理
// 内存描述符
current->mm // 进程内存描述符
current->active_mm // 活跃内存描述符
// 虚拟内存区域
struct vm_area_struct *vma;
for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
// 遍历进程的虚拟内存区域
}
文件系统相关
// 文件系统信息
current->fs // 文件系统信息
current->files // 打开的文件描述符表
// 当前工作目录
struct path pwd = current->fs->pwd;
性能考虑
优势
- 快速访问:直接通过寄存器或简单计算获取
- 无需参数传递:避免在函数间传递task_struct指针
- 架构优化:针对不同架构有优化实现
注意事项
- 原子性:在中断上下文中使用需要小心
- 抢占:在可抢占内核中可能需要禁用抢占
// 安全使用示例
preempt_disable();
struct task_struct *task = current;
// 使用task指针...
preempt_enable();
相关宏和函数
// 相关的有用宏
#define current_uid() (current_cred()->uid)
#define current_gid() (current_cred()->gid)
#define current_euid() (current_cred()->euid)
#define current_egid() (current_cred()->egid)
// 检查函数
static inline bool current_is_single_threaded(void);
static inline bool thread_group_leader(struct task_struct *p);
调试技巧
// 打印当前进程信息的调试函数
void debug_current_process(void)
{
struct task_struct *task = current;
printk(KERN_DEBUG "Current process info:\n");
printk(KERN_DEBUG " PID: %d\n", task->pid);
printk(KERN_DEBUG " COMM: %s\n", task->comm);
printk(KERN_DEBUG " State: %ld\n", task->state);
printk(KERN_DEBUG " Priority: %d\n", task->prio);
}
总结
current
宏是Linux内核开发中最常用的工具之一,它提供了快速、便捷的方式来访问当前进程的信息。
本文版权归原作者zhaofujian所有,采用 CC BY-NC-ND 4.0 协议进行许可,转载请注明出处。