ULK --- Chap3 Processes: How Processes Are Organized
2015-11-09 09:07
405 查看
The runqueue lists group all processes in a TASK_RUNNING state. When it comes to grouping
processes in other states, the various states call for different types of treatment, with Linux
opting for one of choices shown in the following list.
Processes in a TASK_STOPPED, EXIT_ZOMBIE, or EXIT_DEAD state are not linked in specific lists.
There is no need to group processes in any of these three states, because stopped, zombie, and
dead processes are accessed only via PID or via linked lists of child process for a particular parent.
Processes in a TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE state are subdivided into many
classes, each of which corresponds to a specific event. In this case, the process state does not
provide enough information to retrieve the process quickly, so it is necessary to introduce additional
lists of processes. These are called wait queues and are discussed next.
Wait Queues
Wait queues have several uses in the kernel, particularly for interrupt handling, process synchronization,
and timing. Because these topics are discussed in later chapters, we will just say here that a process
must often wait for some events to occur, such as for a disk operation to terminate, a system resource
to be released, or a fixed interval of time to elapse. Wait queues implement conditional waits on events:
a process wishing to wait for a specific event places itself in the proper wait queue and relinquishes control.
Therefore, a wait queue represents a set of sleeping processes, whch are woken up by the kernel when
some condition becomes true.
Wait queues are implemented as doubly linked list whose elements include pointers to process descriptors.
Each wait queue is identified by a wait queue head, a data structure of type wait_queue_head_t:
Because wait queues are modified by interrupt handlers as well as by major kernel functions, the doubly
linked lists must be protected from concurrent accesses, which could include unpredictable results.
Synchronization is achieved by the lock spin lock in the wait queue head. The task_list field is the head of
the list of waiting processes.
Elements of a wait queue list are of type wait_queue_t:
Each element in the wait queue list represents a sleeping process, which is waiting for some event to occur;
its descriptor address is stored in the task field. The task_list field contains the pointers that link this element
to the list of processes waiting for the same event.
However, it is not always convention to wake up all sleeping processes in a wait queue. For instance, if two
or more processes are waiting for exclusive access to some resource to be released, it makes sense to wake
up just one process in the wait queue. This process takes the resource, which the other processes continue to
sleep. (This avoids a problem known as the "thundering herd" with which multiple processes are awaken only
to race for a resource that can be accessed by one of them, with the result that remaining processes must once
more be put back to sleep.)
Thus, there are two kinds of sleeping processes: exclusive processes (denoted by the value 1 in the flags field
of the corresponding wait queue element) are selevtively woken up by the kernel, while nonexclusive processes
(denoted by the value 0 in flags field) are always woken up by the kernel when the event occurs. A process waiting
for a resource that can be granted to just one process at a time is a typical exclusive process. Processes waiting for
an event that may concern any of them are nonexclusive. Consider, for instance, a group of processes that are waiting
for the termination of a group of disk block transfers: as soon as the transfers complete, all waiting processes must
be woken up. As we will see next, the func field of a wait queue element is used to specify how the processes sleeping
in the wait queue should be woken up.
processes in other states, the various states call for different types of treatment, with Linux
opting for one of choices shown in the following list.
Processes in a TASK_STOPPED, EXIT_ZOMBIE, or EXIT_DEAD state are not linked in specific lists.
There is no need to group processes in any of these three states, because stopped, zombie, and
dead processes are accessed only via PID or via linked lists of child process for a particular parent.
Processes in a TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE state are subdivided into many
classes, each of which corresponds to a specific event. In this case, the process state does not
provide enough information to retrieve the process quickly, so it is necessary to introduce additional
lists of processes. These are called wait queues and are discussed next.
Wait Queues
Wait queues have several uses in the kernel, particularly for interrupt handling, process synchronization,
and timing. Because these topics are discussed in later chapters, we will just say here that a process
must often wait for some events to occur, such as for a disk operation to terminate, a system resource
to be released, or a fixed interval of time to elapse. Wait queues implement conditional waits on events:
a process wishing to wait for a specific event places itself in the proper wait queue and relinquishes control.
Therefore, a wait queue represents a set of sleeping processes, whch are woken up by the kernel when
some condition becomes true.
Wait queues are implemented as doubly linked list whose elements include pointers to process descriptors.
Each wait queue is identified by a wait queue head, a data structure of type wait_queue_head_t:
struct __wait_queue_head { spinlock_t lock; struct list_head task_list; }; typedef struct __wait_queue_head wait_queue_head_t;
Because wait queues are modified by interrupt handlers as well as by major kernel functions, the doubly
linked lists must be protected from concurrent accesses, which could include unpredictable results.
Synchronization is achieved by the lock spin lock in the wait queue head. The task_list field is the head of
the list of waiting processes.
Elements of a wait queue list are of type wait_queue_t:
struct __wait_queue { unsigned int flags; struct task_struct* task; wait_queue_func_t func; struct list_head task_list; }; typedef struct __wait_queue wait_queue_t;
Each element in the wait queue list represents a sleeping process, which is waiting for some event to occur;
its descriptor address is stored in the task field. The task_list field contains the pointers that link this element
to the list of processes waiting for the same event.
However, it is not always convention to wake up all sleeping processes in a wait queue. For instance, if two
or more processes are waiting for exclusive access to some resource to be released, it makes sense to wake
up just one process in the wait queue. This process takes the resource, which the other processes continue to
sleep. (This avoids a problem known as the "thundering herd" with which multiple processes are awaken only
to race for a resource that can be accessed by one of them, with the result that remaining processes must once
more be put back to sleep.)
Thus, there are two kinds of sleeping processes: exclusive processes (denoted by the value 1 in the flags field
of the corresponding wait queue element) are selevtively woken up by the kernel, while nonexclusive processes
(denoted by the value 0 in flags field) are always woken up by the kernel when the event occurs. A process waiting
for a resource that can be granted to just one process at a time is a typical exclusive process. Processes waiting for
an event that may concern any of them are nonexclusive. Consider, for instance, a group of processes that are waiting
for the termination of a group of disk block transfers: as soon as the transfers complete, all waiting processes must
be woken up. As we will see next, the func field of a wait queue element is used to specify how the processes sleeping
in the wait queue should be woken up.
相关文章推荐
- android studio 新建工程时提示资源文件出错
- LeetCode Palindrome Number
- adapter的getView()执行过程
- Codeforces Round #330 (Div. 2) A. Vitaly and Night 暴力
- maven下的ssm整合配置步骤
- RHCE 系列(六):安装 Samba 并配置 Firewalld 和 SELinux,和 Windows 共享文件
- 当将Activity的主题Theme设置为Dialog,控制Activity的位置
- UI学习之常用方法
- 根据focus状态改变颜色
- 【eclipse rcp开发】插件内部文件读写方法
- Java—面向对象
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
- IO的五种模型
- chown命令
- 知识链-数据结构
- 你真的会玩SQL吗?你所不知道的 数据聚合
- 五种常见的 PHP 设计模式
- 第一次学习写博客。有些激动,希望自己的总结能够帮助到别人,也希望自己日后总结时能够做到提醒自己。
- windows下实现oracle自动备份 bat
- keil 中——C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法