经典的进程同步问题——临界资源访问
模拟临界资源访问的示例程序
本示例的临界资源是一个建立在共享存储区的栈,由服务进程建立并初始化。初始状态下共享栈满,里面顺序放置一系列正整数(自栈顶向下: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_SHMKEY 10071800 // need to change
#define MAX_BLOCK 1024
#define MAX_CMD 8
struct shmbuf {
int top;
int stack[MAX_BLOCK];
} *shmptr, local;
char cmdbuf[MAX_CMD];
int shmid, semid;
void sigend(int);
void relblock(void);
int 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)
{
/* shared memory exists, act as client */
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