Linux内核代码中的“current”

当我正在浏览下面的Linux字符驱动程序代码块时,我发现printk的结构指针current的。

我想知道current指向什么结构及其完整的元素。

这个结构的目的是什么?

 ssize_t sleepy_read (struct file *filp, char __user *buf, size_t count, loff_t *pos) { printk(KERN_DEBUG "process %i (%s) going to sleep\n", current->pid, current->comm); wait_event_interruptible(wq, flag != 0); flag = 0; printk(KERN_DEBUG "awoken %i (%s)\n", current->pid, current->comm); return 0; } 

Solutions Collecting From Web of "Linux内核代码中的“current”"

它是一个指向当前进程的指针,即发出系统调用的进程。

从文档 :

当前进程

尽管内核模块不像应用程序那样按顺序执行,但内核执行的大多数操作都与特定的进程有关。 内核代码可以通过访问全局项目current来得知驱动它的当前进程,一个指向结构task_struct的指针,内核的版本2.4在<asm/current.h> ,由<linux/sched.h>当前指针指的是当前正在执行的用户进程。 在执行系统调用期间,例如打开或读取,当前进程是调用该调用的进程。 如果需要的话,内核代码可以通过使用current来使用特定于进程的信息。 第5章“增强的字符驱动程序操作”中介绍了此技术的一个示例,即“对设备文件的访问控制”。

实际上,电流不再是一个全局变量,就像在第一个Linux内核中一样。 开发人员通过将其隐藏在堆栈页面中来优化对描述当前进程的结构的访问。 您可以在<asm/current.h>查看当前的细节。 虽然你所看到的代码可能看起来很毛茸茸,但我们必须记住,Linux是一个符合SMP的系统,当你处理多个CPU时,全局变量根本无法工作。 尽管如此,实现的细节对其他内核子系统仍然是隐藏的,设备驱动程序可以只包含和引用当前进程。

从模块的角度来看,电流就像外部参考printk。 模块可以在任何合适的地方引用当前模块。 例如,以下语句通过访问struct task_struct中的某些字段来打印当前进程的进程标识和命令名称:

  printk("The process is \"%s\" (pid %i)\n", current->comm, current->pid); 

存储在current-> comm中的命令名称是当前进程正在执行的程序文件的基本名称。

这是“当前”指向的完整结构

 task_struct Each task_struct data structure describes a process or task in the system. struct task_struct { /* these are hardcoded - don't touch */ volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ long counter; long priority; unsigned long signal; unsigned long blocked; /* bitmap of masked signals */ unsigned long flags; /* per process flags, defined below */ int errno; long debugreg[8]; /* Hardware debugging registers */ struct exec_domain *exec_domain; /* various fields */ struct linux_binfmt *binfmt; struct task_struct *next_task, *prev_task; struct task_struct *next_run, *prev_run; unsigned long saved_kernel_stack; unsigned long kernel_stack_page; int exit_code, exit_signal; /* ??? */ unsigned long personality; int dumpable:1; int did_exec:1; int pid; int pgrp; int tty_old_pgrp; int session; /* boolean value for session group leader */ int leader; int groups[NGROUPS]; /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with * p->p_pptr->pid) */ struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; struct wait_queue *wait_chldexit; unsigned short uid,euid,suid,fsuid; unsigned short gid,egid,sgid,fsgid; unsigned long timeout, policy, rt_priority; unsigned long it_real_value, it_prof_value, it_virt_value; unsigned long it_real_incr, it_prof_incr, it_virt_incr; struct timer_list real_timer; long utime, stime, cutime, cstime, start_time; /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; int swappable:1; unsigned long swap_address; unsigned long old_maj_flt; /* old value of maj_flt */ unsigned long dec_flt; /* page fault count of the last time */ unsigned long swap_cnt; /* number of pages to swap on next pass */ /* limits */ struct rlimit rlim[RLIM_NLIMITS]; unsigned short used_math; char comm[16]; /* file system info */ int link_count; struct tty_struct *tty; /* NULL if no tty */ /* ipc stuff */ struct sem_undo *semundo; struct sem_queue *semsleeping; /* ldt for this task - used by Wine. If NULL, default_ldt is used */ struct desc_struct *ldt; /* tss for this task */ struct thread_struct tss; /* filesystem information */ struct fs_struct *fs; /* open file information */ struct files_struct *files; /* memory management info */ struct mm_struct *mm; /* signal handlers */ struct signal_struct *sig; #ifdef __SMP__ int processor; int last_processor; int lock_depth; /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */ #endif };