linux内核笔记之一

来源:互联网 发布:道道通端口修改工具 编辑:程序博客网 时间:2024/03/28 20:33

1, 说出linux的进程内核堆栈是如何通过SP堆栈指针来找到当前进程的描述符的,并给出这段代码

解答:

先给出内核代码





















内核结构体里已经有pid所以,我们只要调用就可以了。根据函数名就是地址的特性,根据函数的指针传值,好像还可以用结构体传值。

 

2,  进程的两种重要的状态是:

解答:其实进程有很多种状态,有唤醒态、睡眠态、可中断态、不可中断态、运行态、停止态、僵尸态,就绪态、阻塞态、与进程调度有意义的就是运行态和停止态,因为其它的不是异常机制,就是不可调度。

 

3,  给出进程的任务队列中第一个队列元素的数据结构表示


然后是内核原码




解答:linux内核的等待是以双循环链表为基础数据结构,与进程调度机制紧密结合,能够用于实现核心的异步事件通知机制在这个链表中,有两种数据结构:等待列头(wait_queue_head_t)和等待列项(wait_queue_t)等待队列头和等列队列中都包含一个list_head类型的域作为“连接件”。由于我们只需要对队列进行添加和删除操作,并不会修改其中的对象(等待队列项),因此,我们只需要提供一把保护整个基础设施和所有对象的锁,这把锁保存在等待队列头中,为wq_lock类型,通过一个宏定义来切换。如果是自旋锁,将wq_lock_t定义为spinlock_t类型。


无论哪种情况

1>wait queue:<linux/wait.h> __3.0.4
2>description:
在处理推后的工作或阻塞等待某个条件时很有用,wait_queue_func_t func运行在进程上下文.
3>declare or init:

[html] view plaincopy
  1. struct __wait_queue_head {                            
  2.     spinlock_t lock;  
  3.     struct list_head task_list;};  
  4. typedef struct __wait_queue_head wait_queue_head_t;  
  5.   
  6. /* 一个wait queue head可以被定义并静态的初始化 */  
  7. DECLARE_WAIT_QUEUE_HEAD(name);  
  8. /* or 动态的初始化(在代码运行的时候) */  
  9. wait_queue_head_t my_queue;  
  10. init_waitqueue_head(&my_queue);  
4>wait a condition and sleep:
[html] view plaincopy
  1. wait_event(queue, condition)  
  2. wait_event_interruptible(queue, condition)  
  3. wait_event_timeout(queue, condition, timeout)  
  4. wait_event_interruptible_timeout(queue, condition, timeout)  
5>创建并初始化一个'wait queue entry':
[html] view plaincopy
  1. typedef struct __wait_queue wait_queue_t;  
  2. struct __wait_queue {  
  3.     unsigned int flags;  
  4. #define WQ_FLAG_EXCLUSIVE   0x01  
  5.     void *private;  
  6.     wait_queue_func_t func;  
  7.     struct list_head task_list;  
  8. };  
  9. /*  
  10.  * 如果一个wait queue entry设置了WQ_FLAH_EXCLUSIVE标志,  
  11.  * 那么当调用wake_up()唤醒一个等待队列时,  
  12.  * 它会唤醒第一个设置WQ_FLAH_EXCLUSIVE标志的wait queue entry,然后返回.  
  13.  */  
  14. DEFINE_WAIT(my_wait);  
  15. wait_queue_t my_wait;  
  16. init_wait(&my_wait);  
  17.   
  18. #define init_wait(wait)                         \  
  19.     do {                                \  
  20.         (wait)->private = current;              \  
  21.         (wait)->func = autoremove_wake_function;        \  
  22.         INIT_LIST_HEAD(&(wait)->task_list);         \  
  23.         (wait)->flags = 0;                  \  
  24.     } while (0)  
6>add your ‘wait queue entry’ to the queue(waitqueue_head_t):
[html] view plaincopy
  1. /*  
  2.  * queue和wait分别是:wait queue head and the process entry.  
  3.  * state:将是进程的新状态(e.g TASK_INTERRUPTIBLE).  
  4.  */  
  5. void prepare_to_wait(wait_queue_head_t *queue,  
  6.             wait_queue_t *wait,  
  7.             int state);  
  8.   
  9. void prepare_to_wait_exclusive(wait_queue_head_t *queue,  
  10.             wait_queue_t *wait,  
  11.             int state);  
  12.   
  13. /* 也可以,这样将一个‘wait queue entry’添加到指定队列,但是需要单独设置进程的状态. */  
  14. void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);  
  15. void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);  
  16. void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);  
7>通常换出的代码在这里执行:
[html] view plaincopy
  1. /* prepare_to_wait()之后,finish_wait()之前. */  
  2. if(!condition)  
  3.     schedule();  
8>Once schedule() returns, it is cleanup time.
[html] view plaincopy
  1. /* 一些清理工作,把自己移出等待队列 */  
  2. void finish_wait(wait_queue_head_t *queue, wait_queue_t *wait);  
9>唤醒:
[html] view plaincopy
  1. void wake_up(wait_queue_head_t *queue);  
  2. void wake_up_interruptible(wait_queue_head_t *queue);  
  3.   
  4. /* 唤醒wait queue上前nr个独占等待(exclusive) */  
  5. wake_up_nr(wait_queue_head_t *queue, int nr);  
  6. wake_up_interruptible_nr(wait_queue_head_t *queue, int nr);  
  7.   
  8. /* 唤醒所有等待,不管它们是否设置了WQ_FLAG_EXCLUSIVE独占标志 */  
  9. wake_up_all(wait_queue_head_t *queue);  
  10. wake_up_interruptible_all(wait_queue_head_t *queue);  
  11.   
  12. /* 可以理解为一个唤醒的原子版本,*/  
  13. wake_up_interruptible_sync(wait_queue_head_t *queue); 

原创粉丝点击