同样在 Linux 里面,无论是进程,还是线程,到了内核里面,我们统一都叫任务(Task),由一个统一的结构 task_struct 进行管理。这个结构非常复杂,但你也不用怕,我们慢慢来解析。

image.png

  • 链表,将所有的 task_struct 串起来

任务

  1. pid_t pid;
  2. pid_t tgid;
  3. struct task_struct *group_leader;
  • 任务 ID
    • pid: process id
    • tgid: thread group ID

任何一个进程,如果只有主线程,那 pid 是自己,tgid 是自己,group_leader 指向的还是自己。

如果一个进程创建了其他线程,那就会有所变化了。线程有自己的 pid,tgid 就是进程的主线程的 pid,group_leader 指向的就是进程的主线程。

信号处理

  1. /* Signal handlers: */
  2. struct signal_struct *signal;
  3. struct sighand_struct *sighand;
  4. sigset_t blocked;
  5. sigset_t real_blocked;
  6. sigset_t saved_sigmask;
  7. struct sigpending pending;
  8. unsigned long sas_ss_sp;
  9. size_t sas_ss_size;
  10. unsigned int sas_ss_flags;

任务状态

image.png

  1. volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
  2. int exit_state;
  3. unsigned int flags;

所有的可取状态值:

  1. /* Used in tsk->state: */
  2. #define TASK_RUNNING 0
  3. #define TASK_INTERRUPTIBLE 1
  4. #define TASK_UNINTERRUPTIBLE 2
  5. #define __TASK_STOPPED 4
  6. #define __TASK_TRACED 8
  7. /* Used in tsk->exit_state: */
  8. #define EXIT_DEAD 16
  9. #define EXIT_ZOMBIE 32
  10. #define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD)
  11. /* Used in tsk->state again: */
  12. #define TASK_DEAD 64
  13. #define TASK_WAKEKILL 128
  14. #define TASK_WAKING 256
  15. #define TASK_PARKED 512
  16. #define TASK_NOLOAD 1024
  17. #define TASK_NEW 2048
  18. #define TASK_STATE_MAX 4096

image.png

在 Linux 中,有两种睡眠状态:

  • TASK_INTERRUPTIBLE,可中断的睡眠状态
  • TASK_UNINTERRUPTIBLE,不可中断的睡眠状态

新:

  • TASK_KILLABLE,可以终止的新睡眠状态

进程调度

总结

image.png