1、/bin: 存放常用命令/boot: 引导核心的程序目录/dev: 外部设备名/etc: (etcetera)系统管理所要的配置文件和子目录/home:存放用户主目录的地方,一般是/home/用户名。其他目录有ftp、httpd、samba等/lib:(library)系统基本的动态链接库/lost+found/opt :optional(可以选择的)/proc:虚拟系统,是由系统初起时在内存中产生的/root:超级用户默认的主目录;/sbin:系统管理员使用的系统管理程序/tmp:存放各程序执行时所产生的临时文件/usr:占空间最大的目录,用户的很多应用程序和文件几乎全在这个目录中/var:
2、存放一些系统记录文件和配置文件 一、LUNIX的登录与退出1、登录在DOS环境下用MS提供的telnet程序(也可使用WINDOWS 自带的telnet图形界面程序或多功能的S-Term终端程序),可使PC作为终端(terminal)登录(login)UNIX服务器(UNIX Server)。 (1)步骤 login: (输入username) password: (输入密码)2、退出 在LUNIX系统提示符$下,输入logout、exit或shutdown 。例:$ logout二、LUNIX命令格式 命令 选项 处理对象ls -la mydir注意:(1)命令一般是小写字串。注意大小写有别
3、 (2)选项通常以减号(-)再加上一个或数个字符表示,用来选择一个命令的不同操作 (3)同一行可有数个命令,命令间应以分号隔开 (4)命令后加上&可使该命令后台(background)执行二本次实验所用到的指令1.安装U盘:ldisk -lcd /mntmkdir 文件名mount 、dev/sdb1 /mnt/cd /mnt/ls2.编译执行程序:gcc f1.c -o f1.out./f1.out4设计过程1.分析与设计思路分析:通过仔细分析可以知道这是一个进程同步问题的模拟,可以把生产产品或消费产品的每一个过程可以转为一个进程的操作,这些进程是互斥的,同时也存在一定的同步关系。通过编程实
4、践时,实际是随机的调用一个进程的操作,而这些进程的操作相当于程序中的函数调用。而计算机在执行时每一个时刻只能执行一个操作,这就默认了互斥。同步的模拟可以类似于函数调用时的前提关系即先决条件。这样进程同步模拟就完全可以通过进程来实现。具体的每一个操作的对应的进程的关系:实现对缓冲区的初始化:main,要最先执行,且只需要执行一次生产者1生产产品:producer1.c生产者2生产产品:producer2.c消费者1消费产品:consumer1.c消费者2消费产品:consumer2.c在次程序中信号量、共享缓冲区都是系统资源,其总个数是有上限的。每个资源的id在系统中唯一,并且系统不会主动释放它
5、们,所以要小心使用,及时释放。在本程序中:main在执行一次后(成功执行),信号量、共享缓冲区就会分配。如果再执行它,main会提示资源已经分配,则要释放它们。设计思路:设计了4个信号量:semid_empty:表示缓冲区中可以再进行产品添加的空间数semid_full1:表示生产者1所生产的产品数semid_full2:表示生产者2所生产的产品数semid_mux:表示其公共的信号量。设置了4个进程来实现功能:2.各模块流程图P、V操作的流程图:2.生产者与消费者流程图 Y N5源代码与实验结果数据结构void set_sembuf_struct(struct sembuf *sem,int
6、 semnum, int semop,int semflg) /* 设置信号量结构*/ sem-sem_num=semnum;sem_op=semop;sem_flg=semflg; /* sem_num:操作信号在信号集中的编号,第一个信号的编号是0。sem_op:如果其值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。sem_flg:信号操作标志*/主程序:main.c#
7、include sys/ipc.hsys/shm.hsys/sem.herrno.hstring.hstdio.h#define SHMKEY 9075 /*共享存储区的键*/#define SEMKEY_PRODUCER 9085 #define SEMKEY_CONSUMER 9086 #define SEMKEY_MUTEX 9087 /*信号量数组的键*/*注意:上面的键在系统中必须唯一*/#define BUFF_LEN 5 /*缓冲区可以存放5个产品*/#define PRODUCER_LEN 32 /*每个产品是一个字符串:=32字符*/int main() char *addr
8、,end; int shmid;/*共享存储区id*/ int semid_producer,semid_consumer,semid_mutex;/*信号量集合id*/ struct sembuf sem_tmp; /*开辟共享存储区*/ if(shmid=shmget(SHMKEY,BUFF_LEN*PRODUCER_LEN+2,0777|IPC_CREAT|IPC_EXCL)=-1) if(errno=EEXIST) printf(The Buffer Has Existed!n);Do You Want To Delete The Buffer(Y=yes)?n=: scanf(%c,
9、&end); if(end=y|end=Y) /*释放缓冲区*/ shmid=shmget(SHMKEY,BUFF_LEN*PRODUCER_LEN+2,0777); if(shmctl(shmid,IPC_RMID,0)0) perror(shmctl: /*同时释放信号量*/ semid_mutex = semget(SEMKEY_MUTEX,1, 0777); semid_producer = semget(SEMKEY_PRODUCER,1, 0777); semid_consumer = semget(SEMKEY_CONSUMER,1, 0777); semctl(semid_mu
10、tex,0,IPC_RMID); semctl(semid_producer,0,IPC_RMID); semctl(semid_consumer,0,IPC_RMID); elseFail to create buffer! return -1; addr=(char*)shmat(shmid,0,0);/*连接缓冲区,将一个共享存储区附接到它的虚拟地址空间去*/ memset(addr,0,BUFF_LEN*PRODUCER_LEN+2);/*将addr所指向的某一块内存中的每个字节的内容全部设置为0的ASCII值,块的大小由BUFF_LEN*PRODUCER_LEN+2指定,返回值为指向
11、addr的指针*/ shmdt(addr);/*离开缓冲区*/ /*创建信号量*/ if(semid_mutex=semget(SEMKEY_MUTEX,1,0777|IPC_CREAT|IPC_EXCL)=-1)The SEMKEY_MUTEX has existed!Fail to create SEMKEY_MUTEX! if(semid_producer=semget(SEMKEY_PRODUCER,1,0777|IPC_CREAT|IPC_EXCL)=-1)The SEMKEY_PRODUCER has existed!Fail to create SEMKEY_PRODUCER!
12、if(semid_consumer=semget(SEMKEY_CONSUMER,1,0777|IPC_CREAT|IPC_EXCL)=-1)The SEMKEY_CONSUMER has existed!Fail to create SEMKEY_CONSUMER! /*给信号量赋初值*/ set_sembuf_struct(&sem_tmp, 0, BUFF_LEN, 0);/*BUFF_LEN*/ semop(semid_producer, &sem_tmp,1);sem_tmp, 0, 1, 0);/*1*/ semop(semid_mutex, &sem_tmp, 0, 0, 0);
13、/*0*/ semop(semid_consumer, & return 0;/*生产者:producer.c*/#define PRODUCT_LEN 32 /*每个产品是一个字符串:/*下面的P,V是对系统调用的简单封装*/int P(int semid) struct sembuf p_buf; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = 0; if(semop(semid, &p_buf, 1)=-1)/*返回在该组操作中最后被操作的信号量在操作完成前的值*/ perror (p (semid) falsed exit (
14、1); else return (0);int V(int semid) struct sembuf v_buf;/*struct sembuf 参见课件ppt*/ v_buf.sem_num = 0; v_buf.sem_op = 1; v_buf.sem_flg = 0;v_buf, 1)=-1) v (semid) failed main() char *p_buffer;/*共享存储区地址*/ unsigned char in;/*生产者存放产品的指针:它的值存放在全局缓冲区第一个字节*/ char product128;/*事实只使用32B,128为了避免屏幕输入超过32*/ int
15、 semid_producer, semid_consumer, semid_mutex; shmid = shmget(SHMKEY, BUFF_LEN * PRODUCT_LEN+2, 0777);/*连接共享存储区:2 存放in,out的值*/*shmget是建立新的共享区或返回一个已存在的共享描述字*/ p_buffer = (char*)shmat(shmid, 0, 0);/*取共享存储区地址*/*获取全局信号量id*/ /*从屏幕接收产品*/ printf(Please Product(a string ,length = 32B):n=: gets(product);/*128
16、的意义在此,此函数不检查字符串长度*/ /*进入临界区*/ P(semid_producer);/*对私有信号量作P操作*/ P(semid_mutex);/*对公有信号量作P操作*/*二者顺序不能换*/ in = (unsigned char)(*p_buffer); strncpy(p_buffer + 2 + in * PRODUCT_LEN, product, PRODUCT_LEN); in = (in + 1) % BUFF_LEN; *p_buffer = (char)in; shmdt(p_buffer); /*离开缓冲区*/ /*离开临界区*/ V(semid_consumer); V(semid_mutex);/*获取生产者信号量id*/ /*获取消费者信号量id*/#define CONSUMER_LEN 32 /*每个产品是一个字符串:p (s
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1