zoukankan      html  css  js  c++  java
  • 信号量与共享存储区(操作系统实验三)

    实验目的:

    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)> <进程id> started.
    结束时Pro()显示:P <进程id> put an item to <仓库位置>.
    Con()显示:C <进程id> got an item from <仓库位置>.

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<time.h>
    #include<sys/shm.h>
    #include<sys/sem.h>
    #include<sys/types.h>
    #include<sys/ipc.h>
    #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:
    ");
    	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;
    }
    

    未完待续;

  • 相关阅读:
    Unity3d TweenPosition.Begin()的使用浅析
    Unity3D 代理的使用及获取两个碰撞器的碰撞点
    Unity3D 调用GPS位置服务实现代码
    在控制台中输入msqyl一直报ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost'错误
    eclipse 提示错误The method of type must override a superclass method 的解决办法
    Linux高级命令
    Centos7安装及配置
    Linux基本命令
    多线程
    java总结
  • 原文地址:https://www.cnblogs.com/heihuifei/p/9091183.html
Copyright © 2011-2022 走看看