操作系统 实验三 进程同步

集美大学计算机工程学院实验报告

课程名称:操作系统 实验编号: 实验三 班级:计算12 上机实践日期:2015.5 一、实验目的

1、掌握用Linux信号灯集机制实现两个进程间的同步问题。 2、共享函数库的创建 二、实验环境

Ubuntu-VMware、Linux 三、实验内容

? 需要的信号灯: System V信号灯实现

? 用于控制司机是否可以启动车辆的的信号灯 S1=0 ? 用于控制售票员是否可以开门的信号灯 S2=0

指导教师:王丰 实验名称:进程同步 姓名:

上机实践时间: 2学时

实验成绩: 学号:

System V信号灯实现说明

□ System V的信号灯机制属于信号灯集的形式, 一次可以申请多个信号灯. □ 同样利用ftok()生成一个key: semkey=ftok(path,45); □ 利用key申请一个包含有两个信号灯的信号灯集, 获得该集的id semid=semget(semkey,2,IPC_CREAT | 0666); □ 定义一个联合的数据类型 union semun{ int val;

struct semid_ds *buf; ushort *array; };

□ 利用semctl()函数对信号灯初始化,参数有: 信号灯集的id: semid 要初始化的信号灯的编号:sn 要设定的初始值:val

void seminit(int semid, int val,int sn) {

union semun arg; arg.val=val;

semctl(semid,sn,SETVAL,arg);

}

? 利用初始化函数,初始化信号灯:

seminit(semid,0,0);//用来司机启动汽车的同步 seminit(semid,0,1);//用来售票员开门的同步控制

□ 利用semop()函数, 对信号灯实现V操作:sembuf是一个在头部文件中的预定义结构、semid—信号灯集id, sn—要操作的信号灯编号

void semdown(int semid,int sn) {/* define P operating*/ struct sembuf op; op.sem_num=sn;

op.sem_op=-1;//P操作为-1 op.sem_flg=0; semop(semid,&op,1); }

2、Linux的静态和共享函数库

·Linux生成目标代码: gcc -c 源程序文件名(将生成一个与源程序同名的.o目标代码文件。)

·直接用目标代码文件生成可运行文件:gcc –o可执行文件名 目标代码文件 目标代码文件 ?? 源程序文件。

·Linux C有两种风格的函数库:静态函数库、共享函数库 ·生成一个静态函数库

ar r libtools.a m1.o m2.o m3.o ?? ar --Linux的归档命令。

r—表示生成一个名字为libtools.a的静态函数库

·使用自己创建的静态函数库:gcc -o可执行文件名源程序 目标模块 静态函数库名 ·在链接时也可以使用如下参数:gcc 源程序 目标模块 -L函数库位置 -l函数库名 ·生成自己的共享函数库:

生成共享函数库和生成一个程序一样简单。

gcc m1.o m2.o ?? mn.o –shared -o共享函数库名

·使用自己的共享函数库:在文件“/etc/ld.so.conf”设定(具有root权限) ·运行/sbin/ldconfig,用文件/etc/ld.so.conf的内容更新缓存文件/etc/ld.so.cache

四、实验步骤

1、信号灯集机制实现司机与售票员问题

#include #include #include #include #include #include union semun{

int val;//仅用于SETVAL命令

struct semid_ds *buf;//用于IPC_SET等命令 ushort *array;//用于SETALL等命令 };

//用于信号灯初始化 //semid--信号灯的ID

//val--欲设置的信号灯初值 //sn--信号灯集的分量

void seminit(int semid,int val,int sn) {

union semun arg; arg.val=val;

semctl(semid,sn,SETVAL,arg); };

//实现信号灯的P操作 //semid--信号灯的ID //sn--信号灯集的分量

void semdown(int semid,int sn) {/* define P operating*/ struct sembuf op; op.sem_num=sn;

op.sem_op=-1;//P操作为-1 op.sem_flg=0;

semop(semid,&op,1); }

//实现信号灯的V操作

seminit(semid,0,1);//对信号灯集的1号分量进行初始化 if(fork()==0) //Create a process {//子进程作为驾驶员进程 do{

semdown(semid,0);//等待售票员关门

printf(\ printf(\

rrand=1+(int)(6.0*rand()/(RAND_MAX+1.0));//产生一个(1-6)的随机数表示车辆的行驶时间

sleep(rrand);

printf(\ semup(semid,1);//唤醒售票员 }while(1); } else

{//父进程作为售票员进程 do{

printf(\

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4