信号量与共享存储区(操作系统实验三)

实验目的:

1.熟悉Linux环境下的多进程编程

2.熟悉Linux的信号量与共享存储区的使用

3.加深对生产者/消费者(PC)问题的理解

实验环境:

Ubuntu 12.4(32位,简体中文)

实验内容:

1.编写程序,构建父进程逻辑与紫子进程逻辑框架;
2.对信号量操作进行再次封装,实现以下函数:

MySem newsem(int initVal)
:创建新的信号量,初值为initVal,完成后返回信号量的ID(typedef int MySem;)

void psem(MySem semID):对ID为semID的信号量做p

void vsem(MySemsemID):对ID为semID的信号量做v

void freesem(MySemsemID):注销ID为semID的信号量

3.在init()中添加代码,请求用户输入仓库库存,然后申请并初始化共享存储区(仓库数组和变量in、out),以及所各种信号量。

4.在Pro()和Con()中添加代码,完成复杂PC问题(多生产者、多消费者)的模拟。
其中Pro()和Con()开始时在屏幕显示
<进程类型(P或C)> started.
结束时Pro()显示:P put an item to .
Con()显示:C got an item from .

#include
#include
#include
#include
#include
#include
#include
#include
#define PRO 1
#define CON 0
#define p -1
#define v +1
int empty,full,mutex1,mutex2;
int *buf;
int newsem(int intval)      //新建信号量
{
    int r,semID;
    semID=semget(0,1,IPC_CREATE|0666);  //创建新的信号量集并可读写
    r=semctl(semID,0,SETVAL,intval);    //对制定信号量赋值为intval,若成功则,返回一个正数,否则返回一个负数;
    return semID;
}
void psem(int semID)            //对ID为semID的信号量做p操作;
{
    struct sembuf s;
    s.sem_num=0;            //欲操作的信号量在信号集中的编号
    s.sem_op=p;         //信号量PV操作的增量
    s.sem_flg=0;            //额外选项标识(0表示无额外设置,IPC_NOWAIT表示不允许阻塞,SEM_UNDO表示进程结束时回复信号量等)

    int r=semop(semID,&s,1);    //对指定的semID信号量执行p操作
}
void vsem(int semID)            //对ID为semID的信号量做操作;
{
    struct sembuf s;
        s.sem_num=0;                    //欲操作的信号量在信号集中的编号
        s.sem_op=v;                     //信号量PV操作的增量
        s.sem_flg=0;                    //额外选项标识(0表示无额外设置,$

        int r=semop(semID,&s,1);        //对指定的semID信号量执行v操作
}
void freesem(int semID)
{
    int r;
    r=semctl(semID,0,IPC_RMID); //IPC_RMID:表示注销信号量集,不需要参数;

}
int init(int n)
{
    int shpid;
    shpid=shmget(0,sizeof(int)*(n+2),IPC_CREAT|0666);//create共享存储区+2 in out
    buf=(int *)shmat(shpid,0,0);    //将共享存储区映射到用户进程空间;
    empty=newsem(n);        //缓冲区单元格有n个,初始化标记为null,允许生产者进程一开始就连续执行k次;
    full=newsem(0);         //初始时,没有满标记单元格,置初值full=0;
    mutex1=newsem(1);       //生产者的互斥;
    mutex2=newsem(1);       //消费者的互斥;
    buf[n]=0;           //缓冲区单元格in;
    buf[n+1]=0;         //缓冲区单元格out;
    return shpid;           //存储区id;
}
void pro()
{
}
void con()
{
}
int main()
{
    int t,k,n;
    printf("请输入仓库库存n:\n");
    scanf("%d",&n);
    int shpid=init(n);
    k=rand()%1+1;
    pid_t pid;      //定义进程标示符;
    while(1)
    {
        srand((unsigned)time(NULL));    //每次置随机数种子;
        pid=fork();         //建立一个新的子进程,在父进程返回的时子进程的ID,在子进程返回0;
        if(pid==0)  //子进程;
        {
            t=rand()%2; //0,1
            if(t==PRO)
                pro(pid,n);
            else if(t==CON)
                con(pid,n);
            return 0;
        }
        else        //父进程;
            sleep(rand()%3);
    }
    int x1=shmdt(0);    //断开已有的映射
    int x2=shctl(shpid,IPC_RMID,0);
    return 0;
}

未完待续;

转载于:https://www.cnblogs.com/heihuifei/p/9091183.html

你可能感兴趣的:(信号量与共享存储区(操作系统实验三))