在linux核心程序排程函數schedule()中定義了struct task_struct **p,它是指向指針的指針,由于linux核心中task數組定義如下:
struct task_struct *task[NR_TASKS] = { &(init_task.task), };
/*
* 'schedule()' is the scheduler function. This is GOOD CODE! There
* probably won't be any reason to change this, as it should work well
* in all circumstances (ie gives IO-bound processes good response etc).
* The one thing you might take a look at is the signal-handler code here.
*
* NOTE!! Task 0 is the 'idle' task, which gets called when no other
* tasks can run. It can not be killed, and it cannot sleep. The 'state'
* information in task[0] is never used.
*/
void schedule(void)
{
int i,next,c;
struct task_struct ** p;
/* check alarm, wake up any interruptible tasks that have got a signal */
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p) {
if ((*p)->alarm && (*p)->alarm < jiffies) {
(*p)->signal |= (1<<(SIGALRM-1));
(*p)->alarm = 0;
}
if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&
(*p)->state==TASK_INTERRUPTIBLE)
(*p)->state=TASK_RUNNING;
}
/* this is the scheduler proper: */
while (1) {
c = -1;
next = 0;
i = NR_TASKS;
p = &task[NR_TASKS];
while (--i) {
if (!*--p)
continue;
if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
c = (*p)->counter, next = i;
}
if (c) break;
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p)
(*p)->counter = ((*p)->counter >> 1) +
(*p)->priority;
}
switch_to(next);
}
其中LAST_TASK 定義為 task[NR_TASK], FIRST_TASK 定義為 task[0],task[]數組是一組指針,它指向的是每個task在記憶體中的存儲
位址。*p即取p的内容,它内容的含義就是指向實際任務控制塊在記憶體的位置,也就是task[i]的内容(指針的值)
下面是自己為了更好了解指針的指針寫的一個小執行個體
pointer.h
typedef unsigned int sigset_t;
typedef struct desc_struct {
unsigned long a,b;
} desc_table[256];
struct i387_struct {
long cwd;
long swd;
long twd;
long fip;
long fcs;
long foo;
long fos;
long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
};
struct sigaction {
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
struct tss_struct {
long back_link; /* 16 high bits zero */
long esp0;
long ss0; /* 16 high bits zero */
long esp1;
long ss1; /* 16 high bits zero */
long esp2;
long ss2; /* 16 high bits zero */
long cr3;
long eip;
long eflags;
long eax,ecx,edx,ebx;
long esp;
long ebp;
long esi;
long edi;
long es; /* 16 high bits zero */
long cs; /* 16 high bits zero */
long ss; /* 16 high bits zero */
long ds; /* 16 high bits zero */
long fs; /* 16 high bits zero */
long gs; /* 16 high bits zero */
long ldt; /* 16 high bits zero */
long trace_bitmap; /* bits: trace 0, bitmap 16-31 */
struct i387_struct i387;
};
struct task_struct {
/* these are hardcoded - don't touch */
long state; /* -1 unrunnable, 0 runnable, >0 stopped */
long counter;
long priority;
long signal;
struct sigaction sigaction[32];
long blocked; /* bitmap of masked signals */
/* various fields */
int exit_code;
unsigned long start_code,end_code,end_data,brk,start_stack;
long pid,father,pgrp,session,leader;
unsigned short uid,euid,suid;
unsigned short gid,egid,sgid;
long alarm;
long utime,stime,cutime,cstime,start_time;
unsigned short used_math;
/* file system info */
int tty; /* -1 if no tty, so it must be signed */
unsigned short umask;
struct m_inode * pwd;
struct m_inode * root;
struct m_inode * executable;
unsigned long close_on_exec;
struct file * filp[20];
/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
struct desc_struct ldt[3];
/* tss for this task */
struct tss_struct tss;
};
struct task_struct *task[64];
struct task_struct _task[64];
pointer.c
#include "pointer.h"
#include<stdio.h>
#define FIRST_TASK task[0]
#define LAST_TASK task[63]
int main(void)
{
int i;
for(i=0;i<64;++i)
{
_task[i].counter=(long)i;
task[i]=&_task[i];
}
struct task_struct *p;
struct task_struct **q;
printf("sizeof task_struct is %d/n",sizeof(p));
long tmp;
//printf("%d/n",(&LAST_TASK)->counter);
//*p=&LAST_TASK;
//printf("%d/n",(*p)->counter);
for(p=LAST_TASK;p>FIRST_TASK;--p)
{
printf("task[%d] : 0x%x &task[%d] : 0x%x/n",p->counter,p,p->counter,&p);
//printf("After SUB %d/n",tmp-(long)p);
//tmp=p;
//if(p)
//printf("process %d is runing/n",(p)->counter);
}
for(q=&LAST_TASK;q>&FIRST_TASK;--q)
{
printf("task[%d] : 0x%x &task[%d] : 0x%x/n",(*q)->counter,*q,(*q)->counter,q);
//printf("After SUB %d/n",tmp-(long)p);
//tmp=p;
//if(*q)
//printf("process %d is runing/n",(*q)->counter);
}
return 0;
}
makefile
pointer:pointer.o
gcc -o pointer pointer.o
pointer.o:pointer.c
gcc -g -c pointer.c
clean:
-rm -f pointer pointer.o
程式運作輸出:
sizeof task_struct is 4
task[63] : 0x8058204 &task[63] : 0xbfb8fc90
task[62] : 0x8057e48 &task[62] : 0xbfb8fc90
task[61] : 0x8057a8c &task[61] : 0xbfb8fc90
task[60] : 0x80576d0 &task[60] : 0xbfb8fc90
task[59] : 0x8057314 &task[59] : 0xbfb8fc90
task[58] : 0x8056f58 &task[58] : 0xbfb8fc90
task[57] : 0x8056b9c &task[57] : 0xbfb8fc90
task[56] : 0x80567e0 &task[56] : 0xbfb8fc90
task[55] : 0x8056424 &task[55] : 0xbfb8fc90
task[54] : 0x8056068 &task[54] : 0xbfb8fc90
task[53] : 0x8055cac &task[53] : 0xbfb8fc90
task[52] : 0x80558f0 &task[52] : 0xbfb8fc90
task[51] : 0x8055534 &task[51] : 0xbfb8fc90
task[50] : 0x8055178 &task[50] : 0xbfb8fc90
task[49] : 0x8054dbc &task[49] : 0xbfb8fc90
task[48] : 0x8054a00 &task[48] : 0xbfb8fc90
task[47] : 0x8054644 &task[47] : 0xbfb8fc90
task[46] : 0x8054288 &task[46] : 0xbfb8fc90
task[45] : 0x8053ecc &task[45] : 0xbfb8fc90
task[44] : 0x8053b10 &task[44] : 0xbfb8fc90
task[43] : 0x8053754 &task[43] : 0xbfb8fc90
task[42] : 0x8053398 &task[42] : 0xbfb8fc90
task[41] : 0x8052fdc &task[41] : 0xbfb8fc90
task[40] : 0x8052c20 &task[40] : 0xbfb8fc90
task[39] : 0x8052864 &task[39] : 0xbfb8fc90
task[38] : 0x80524a8 &task[38] : 0xbfb8fc90
task[37] : 0x80520ec &task[37] : 0xbfb8fc90
task[36] : 0x8051d30 &task[36] : 0xbfb8fc90
task[35] : 0x8051974 &task[35] : 0xbfb8fc90
task[34] : 0x80515b8 &task[34] : 0xbfb8fc90
task[33] : 0x80511fc &task[33] : 0xbfb8fc90
task[32] : 0x8050e40 &task[32] : 0xbfb8fc90
task[31] : 0x8050a84 &task[31] : 0xbfb8fc90
task[30] : 0x80506c8 &task[30] : 0xbfb8fc90
task[29] : 0x805030c &task[29] : 0xbfb8fc90
task[28] : 0x804ff50 &task[28] : 0xbfb8fc90
task[27] : 0x804fb94 &task[27] : 0xbfb8fc90
task[26] : 0x804f7d8 &task[26] : 0xbfb8fc90
task[25] : 0x804f41c &task[25] : 0xbfb8fc90
task[24] : 0x804f060 &task[24] : 0xbfb8fc90
task[23] : 0x804eca4 &task[23] : 0xbfb8fc90
task[22] : 0x804e8e8 &task[22] : 0xbfb8fc90
task[21] : 0x804e52c &task[21] : 0xbfb8fc90
task[20] : 0x804e170 &task[20] : 0xbfb8fc90
task[19] : 0x804ddb4 &task[19] : 0xbfb8fc90
task[18] : 0x804d9f8 &task[18] : 0xbfb8fc90
task[17] : 0x804d63c &task[17] : 0xbfb8fc90
task[16] : 0x804d280 &task[16] : 0xbfb8fc90
task[15] : 0x804cec4 &task[15] : 0xbfb8fc90
task[14] : 0x804cb08 &task[14] : 0xbfb8fc90
task[13] : 0x804c74c &task[13] : 0xbfb8fc90
task[12] : 0x804c390 &task[12] : 0xbfb8fc90
task[11] : 0x804bfd4 &task[11] : 0xbfb8fc90
task[10] : 0x804bc18 &task[10] : 0xbfb8fc90
task[9] : 0x804b85c &task[9] : 0xbfb8fc90
task[8] : 0x804b4a0 &task[8] : 0xbfb8fc90
task[7] : 0x804b0e4 &task[7] : 0xbfb8fc90
task[6] : 0x804ad28 &task[6] : 0xbfb8fc90
task[5] : 0x804a96c &task[5] : 0xbfb8fc90
task[4] : 0x804a5b0 &task[4] : 0xbfb8fc90
task[3] : 0x804a1f4 &task[3] : 0xbfb8fc90
task[2] : 0x8049e38 &task[2] : 0xbfb8fc90
task[1] : 0x8049a7c &task[1] : 0xbfb8fc90
task[63] : 0x8058204 &task[63] : 0x80586bc
task[62] : 0x8057e48 &task[62] : 0x80586b8
task[61] : 0x8057a8c &task[61] : 0x80586b4
task[60] : 0x80576d0 &task[60] : 0x80586b0
task[59] : 0x8057314 &task[59] : 0x80586ac
task[58] : 0x8056f58 &task[58] : 0x80586a8
task[57] : 0x8056b9c &task[57] : 0x80586a4
task[56] : 0x80567e0 &task[56] : 0x80586a0
task[55] : 0x8056424 &task[55] : 0x805869c
task[54] : 0x8056068 &task[54] : 0x8058698
task[53] : 0x8055cac &task[53] : 0x8058694
task[52] : 0x80558f0 &task[52] : 0x8058690
task[51] : 0x8055534 &task[51] : 0x805868c
task[50] : 0x8055178 &task[50] : 0x8058688
task[49] : 0x8054dbc &task[49] : 0x8058684
task[48] : 0x8054a00 &task[48] : 0x8058680
task[47] : 0x8054644 &task[47] : 0x805867c
task[46] : 0x8054288 &task[46] : 0x8058678
task[45] : 0x8053ecc &task[45] : 0x8058674
task[44] : 0x8053b10 &task[44] : 0x8058670
task[43] : 0x8053754 &task[43] : 0x805866c
task[42] : 0x8053398 &task[42] : 0x8058668
task[41] : 0x8052fdc &task[41] : 0x8058664
task[40] : 0x8052c20 &task[40] : 0x8058660
task[39] : 0x8052864 &task[39] : 0x805865c
task[38] : 0x80524a8 &task[38] : 0x8058658
task[37] : 0x80520ec &task[37] : 0x8058654
task[36] : 0x8051d30 &task[36] : 0x8058650
task[35] : 0x8051974 &task[35] : 0x805864c
task[34] : 0x80515b8 &task[34] : 0x8058648
task[33] : 0x80511fc &task[33] : 0x8058644
task[32] : 0x8050e40 &task[32] : 0x8058640
task[31] : 0x8050a84 &task[31] : 0x805863c
task[30] : 0x80506c8 &task[30] : 0x8058638
task[29] : 0x805030c &task[29] : 0x8058634
task[28] : 0x804ff50 &task[28] : 0x8058630
task[27] : 0x804fb94 &task[27] : 0x805862c
task[26] : 0x804f7d8 &task[26] : 0x8058628
task[25] : 0x804f41c &task[25] : 0x8058624
task[24] : 0x804f060 &task[24] : 0x8058620
task[23] : 0x804eca4 &task[23] : 0x805861c
task[22] : 0x804e8e8 &task[22] : 0x8058618
task[21] : 0x804e52c &task[21] : 0x8058614
task[20] : 0x804e170 &task[20] : 0x8058610
task[19] : 0x804ddb4 &task[19] : 0x805860c
task[18] : 0x804d9f8 &task[18] : 0x8058608
task[17] : 0x804d63c &task[17] : 0x8058604
task[16] : 0x804d280 &task[16] : 0x8058600
task[15] : 0x804cec4 &task[15] : 0x80585fc
task[14] : 0x804cb08 &task[14] : 0x80585f8
task[13] : 0x804c74c &task[13] : 0x80585f4
task[12] : 0x804c390 &task[12] : 0x80585f0
task[11] : 0x804bfd4 &task[11] : 0x80585ec
task[10] : 0x804bc18 &task[10] : 0x80585e8
task[9] : 0x804b85c &task[9] : 0x80585e4
task[8] : 0x804b4a0 &task[8] : 0x80585e0
task[7] : 0x804b0e4 &task[7] : 0x80585dc
task[6] : 0x804ad28 &task[6] : 0x80585d8
task[5] : 0x804a96c &task[5] : 0x80585d4
task[4] : 0x804a5b0 &task[4] : 0x80585d0
task[3] : 0x804a1f4 &task[3] : 0x80585cc
task[2] : 0x8049e38 &task[2] : 0x80585c8
task[1] : 0x8049a7c &task[1] : 0x80585c4