模拟临界资源访问的示例程序本示例的临界资源是一个建立在共享存储区的栈,由服务进程建立并初始化。初始状态下共享栈满,里面顺序放置一系列正整数(自栈顶向下:1,2,3...),代表空闲块号。客户进程利用共享栈进行数据块的分配和释放,以得到、归还一个块号代表,并不进行任何后续操作。程序中getblock过程从共享栈中弹出一个块号(分配),relblock过程把一个已分配块号压入共享栈(释放)。为简单起见,已分配块号在本地也使用栈结构保存,因而每次释放的是最后分配的块号。
编译后执行,第一个进程实例将作为服务进程,提示:
NO OTHER OPERATION but press Ctrl+C or use kill to end.
服务进程完成初始化后将进入睡眠状态,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。
其他进程实例作为客户进程,进入后首先有命令帮助提示,然后显示命令提示符“?>”,在命令提示下可以使用的命令包括:
help 显示可用命令
list 列出所有已分配块号
get 分配一个新块
rel 释放最后分配块号
end 退出程序
示例程序的代码如下:
#include<sys/types.h> #include<unistd.h> #include<signal.h> #include<stdio.h> #include<string.h> #include<sys/ipc.h> #include<sys/shm.h> #define MY_SHMKEY10071800 // need to change #define MAX_BLOCK 1024 #define MAX_CMD 8 //共享存储区的栈结构 //为简单起见,已分配块号在本地也使用栈结构local保存 struct shmbuf { int top; intstack[MAX_BLOCK]; } *shmptr, local; // char cmdbuf[MAX_CMD]; int shmid, semid; void sigend(int); void relblock(void);//释放最后分配块号 void getblock(void);//分配一个新块 void showhelp(void);//显示可用命令 void showlist(void);//列出所有已分配块号 void getcmdline(void);//接受输入命令 int main(void) { //建立一个共享存储区 if((shmid=shmget(MY_SHMKEY, sizeof(struct shmbuf),IPC_CREAT|IPC_EXCL|0666)) < 0) { //获得共享存储区首地址 shmid=shmget(MY_SHMKEY, sizeof(struct shmbuf), 0666); //把一个共享存储区附接到进程内存空间; shmptr=(struct shmbuf *)shmat(shmid, 0, 0); //初始化 local.top=-1; //输出命令提示 showhelp(); //接受输入命令 getcmdline(); while(strcmp(cmdbuf,"end\n")) { if(!strcmp(cmdbuf,"get\n")) getblock(); else if(!strcmp(cmdbuf,"rel\n")) relblock(); else if(!strcmp(cmdbuf,"list\n")) showlist(); else if(!strcmp(cmdbuf,"help\n")) showhelp(); //接受输入命令 getcmdline(); } } else { int i; //把一个共享存储区附接到进程内存空间; shmptr=(struct shmbuf *)shmat(shmid, 0, 0); //设置对信号的处理方式或处理过程 signal(SIGINT, sigend); signal(SIGTERM, sigend); printf("NO OTHER OPERATION but press Ctrl+C or use kill toend.\n"); //初始状态下共享栈满,里面顺序放置一系列正整数(自栈顶向下:,2,3...), //代表空闲块号 shmptr->top=MAX_BLOCK-1;//shmptr->top值越大,可利用物理块就越多 for(i=0; i<MAX_BLOCK; i++) shmptr->stack=MAX_BLOCK-i; sleep(1000000); } } |