Linux进程互斥——临界资源访问
(2009-11-28 22:57:57)
标签:
数据块if进程互斥ipcto存储区 |
模拟临界资源访问的示例程序
本示例的临界资源是一个建立在共享存储区的栈,由服务进程建立并初始化。初始状态下共享栈满,里面顺序放置一系列正整数(自栈顶向下:1,2,3...),代表空闲块号。客户进程利用共享栈进行数据块的分配和释放,以得到、归还一个块号代表,并不进行任何后续操作。程序中getblock过程从共享栈中弹出一个块号(分配),relblock过程把一个已分配块号压入共享栈(释放)。为简单起见,已分配块号在本地也使用栈结构保存,因而每次释放的是最后分配的块号。
编译后执行,第一个进程实例将作为服务进程,提示:
服务进程完成初始化后将进入睡眠状态,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。
其他进程实例作为客户进程,进入后首先有命令帮助提示,然后显示命令提示符“?> ”,在命令提示下可以使用的命令包括:
#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
#define MAX_BLOCK 1024
#define MAX_CMD 8
//共享存储区的栈结构
//为简单起见,已分配块号在本地也使用栈结构local保存
struct shmbuf
{
} *shmptr, local;
//
char cmdbuf[MAX_CMD];
int shmid, semid;
void sigend(int);
void relblock(void);//释放最后分配块号
void
void showhelp(void);//显示可用命令
void showlist(void);//列出所有已分配块号
void getcmdline(void);//接受输入命令
int main(void)
{
}
void sigend(int sig)
{
}
void relblock(void)
{
}
void
{
}
//显示可用命令
void showhelp(void)
{
}
//列出所有已分配块号
void showlist(void)
{
}
//接受输入命令
void getcmdline(void)
{
fgets(cmdbuf, MAX_CMD-1, stdin);
}
2、模拟临界资源访问
实现相应的示例程序功能,记录执行结果,
运行结果:
看是否能观察到程序出现错误情况;
不能。
改造该程序,使错误情况易于观察到,记录执行情况并进行分析;
分析:
为了使错误易于观察,在分配和释放数据块的函数relblock(void)和 getblock(void)改为如下:
void relblock(void)
{
}
void
{
}
打开两个终端,即两个申请数据块的进程按照如下运行,及结果:
1》错误一:两个进程同时申请数据块,即get——get。两个进程同时得到了数据块号3,
运行结果如下:
进程一:
进程二:
具体执行代码顺序如下:
1>shmptr->top--;
2>shmptr->top--;
错误二:一个进程释放数据块,一个进程申请数据块时,则出错。
运行结果如下:无效的数据块6,再次被分配,错误。
进程一:
进程二:
具体执行代码顺序如下:
2>shmptr->top--;
利用信号量机制实现进程互斥功能,记录执行结果,并进行对比分析。
分析:利用信号量sign来实现同时执行getblock(),即申请数据块。或者先执行relblock()再执行getblock() 即,先申请数据块再申请数据块。的互斥。同理有relblock() 和getblock(),relblock()和getblock()也会出现类似错误。
为了方面实现,在上一个代码基础上,在结构shmbuf的定义中添加了信号量sign的定义。之后在代码中进行pv操作。代码如下:
#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
#define MAX_BLOCK 1024
#define MAX_CMD 8
//共享存储区的栈结构
//为简单起见,已分配块号在本地也使用栈结构local保存
struct shmbuf
{
} *shmptr, local;
//
char cmdbuf[MAX_CMD];
int shmid, semid;
void sigend(int);
void relblock(void);//释放最后分配块号
void
void showhelp(void);//显示可用命令
void showlist(void);//列出所有已分配块号
void getcmdline(void);//接受输入命令
int main(void)
{
}
void sigend(int sig)
{
}
void relblock(void)
{
}
void
{
}
//显示可用命令
void showhelp(void)
{
}
//列出所有已分配块号
void showlist(void)
{
}
//接受输入命令
void getcmdline(void)
{
}