1 本实验是一个使用自旋锁(spinlock)来实现进程调度的问题,此外还会牵涉到共享内存(SHM)的知识,在多个进程之间共享数据,以前只知道利用管道,但管道只能用于父子进程之间,所以必须使用共享内存来实现数据的共享。 对于spinlock,为了更好的理解OS 内核的加锁机制,要求使用汇编指令实现,因为这样更贴近系统层。所以得用C语言与汇编语言混合编程,这个是本实验的一个重点,同时也是难点所在。 有了spinlock,就能够对进程调度了,先使用fork()及execl 调用产生init、monitor、processA、processB 和 processC 等五个进程,其中 init 进程是对共享内存进行初始化,processA、processB 和 processC 进程是三个应用进程,这三个应用进程受 monitor 监控进程控制运行,是按照先processA 然后 processB 最后processC 依次运行。 二、实验步骤: (1)开辟共享内存及其初始化,这项操作是需要init 进程完成,使用共享内存一般步骤如下: 1.开辟一块共享内存 shmget() 2.允许本进程使用共某块共享内存 shmat() 3.写入/读出 4.禁止本进程使用这块共享内存 shmdt() 5.删除这块共享内存 shmctl()或者命令行下 ipcrm 下面对如何创建共享内存做个简单说明: 函数原型:int shmget( key_t shmkey , int shmsiz , int flag ); 在新创建一片共享内存时,先通过 ftok 函数计算一个标识符,即参数shmkey,shmsiz 为所要开辟空间的大小,flag 为这块内存的权限标志,新建为IPC_CREAT。 共享内存的初始化操作实现要借助于shmat()函数,这个函数是通过这块内存的ID 号,返回内存的首地址。得到那片共享内存的首地址后,初始化操作就变成简单的赋值操作了。 下面即为开辟内存即初始化的源码: indata = (int*)&_sharedSpace; //获取共享数据结构体的首地址 shmkey = ftok("share",'a'); //计算标识符 //开辟内存 shmid = shmget(shmkey,sizeof(sharedSpace),IPC_CREAT|0666); head = pos = shmat(shmid, 0, 0); //返回共享空间首地址 for(i = 0;i < 9;i++){ *(pos++) = *(indata++); //写入共享内存 } (2) 自旋锁的实现 int spin_lock(int *p) { asm( "pushl %%eax; \n\t" "pushl %%ecx; \n\t" "l1: movl %1, %%ecx; \n\t" "movl %2, %%eax; \n\t" 2 "lock cmpxchgl %%ecx, %0; \n\t" "jne l1; \n\t" "popl %%ecx; \n\t" "popl %%eax; ...