1、进程状态
TASK_RUNNING 运行状态
TASK_INTERRUPTIBLE 可被信号唤醒状态
TASK_UNINTERRUPTIBLE 不可被信号唤醒状态
TASK_STOPPED 进程执行被暂停状态
TASK_TRACED 进程执行已由debugger跟踪状态
EXIT_ZOMBIE 进程死亡等待父进程回收状态
EXIT_DEAD 进程死亡正在被回收状态
EXIT_ZOMBIE和EXIT_DEAD比较特殊可以被task_struct->state保存也可以被task_struct->exit_state保存
struct task_struct{
...
pid_t pid;
pid_t tgid;
}
进程一般被pid标识,pid与task_struct是一一对应的关系,一般单线程的进程tgid是与pid相等,但是多线程的进程tgid等于线程组中的头号线程pid,当然头号线程的tgid等于自身的pid,所以一般的getpid返回的是task_struct的tgid值而非pid值
在linux-4.4中紧挨着的是thread_info类型的数据结构
struct thread_info {
struct task_struct *task; /* main task structure */ 8
__u32 flags; /* low level flags */ 4
__u32 status; /* thread synchronous flags */ 4
__u32 cpu; /* current CPU */ 4
mm_segment_t addr_limit; 8
unsigned int sig_on_uaccess_error:1; 4
unsigned int uaccess_err:1; /* uaccess failed */ 4
};
设置进程状态
#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
_THIS_IP_宏是作为函数内部的一个label
#define set_task_state(tsk, state_value) \
do { \
(tsk)->task_state_change = _THIS_IP_; \
smp_store_mb((tsk)->state, (state_value)); \
} while (0)
还有个设置当前进程状态的宏:
#define set_current_state(state_value) \
do { \
current->task_state_change = _THIS_IP_; \
smp_store_mb(current->state, (state_value)); \
} while (0)
等价于(tsk)->task_state_change = 函数内部此处label地址
(tsk)->state=(state_value)
4.4内核中都是讲thread_info 和内核栈定义位一个联合体
#ifdef CONFIG_KASAN
#define KASAN_STACK_ORDER 1
#else
#define KASAN_STACK_ORDER 0
#endif
#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER)
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
union thread_union {
struct thread_info thread_info;
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
这样实际上分配了2页内存的栈但是实际可用的是8192-sizeof(thread_info)
current_thread_info宏获取当前jtask_struct对应的thread_info 结构
static inline struct thread_info *current_thread_info(void)
{
return (struct thread_info *)(current_top_of_stack() - THREAD_SIZE);
}