课程实验报告
课程名称: 操 作 系 统 原 理
专业班级:
学 号:
姓 名:
指导教师:
报告日期:
计算机科学与技术学院
目录
目录................................................................................................................................. 2
实验一:线程的同步........................................................................................................ 3
一、实验目的............................................................................................................ 3
二、实验内容............................................................................................................ 3
三、实验心得............................................................................................................ 6
实验二:誊抄实验的进程实现.......................................................................................... 7
一、实验目的............................................................................................................ 7
二、实验内容............................................................................................................ 7
三、实验心得.......................................................................................................... 10
实验三:Linux文件目录操作.......................................................................................... 12
一、实验目的.......................................................................................................... 12
二、实验内容.......................................................................................................... 12
三、实验心得.......................................................................................................... 14
实验一:线程的同步
一、实验目的
1、掌握Linux系统用户界面中键盘命令的使用。
2、学会一种Linux下的编程环境。
3、掌握Linux下进(线)程的概念。
4、了解Linux进程同步与通信的主要机制,并通过信号灯操作实现进程间的同步与互斥。
二、实验内容
1、程序要求
两个线程,共享公共变量a
线程1负责计算(+1)
线程2负责打印
2、运行环境
软件配置(含操作系统版本):ubuntu - 14.10
硬件:PC
3、源程序
源程序:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/ipc.h>
int semid;
int a=0;
typedef union senum
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *_buf;
}SEM_CTL_UN;
void P(int semid,int index)
{
struct sembuf sem;
sem.sem_num = index;
sem.sem_op = -1;//P
sem.sem_flg = 0;//biaoji
semop(semid,&sem,1);
}
void V(int semid,int index)
{
struct sembuf sem;
sem.sem_num = index;
sem.sem_op = 1;
sem.sem_flg = 0;
semop(semid,&sem,1);
}
void* thread1(void *arg)
{
int i=0;
for(i;i<8;i++)
{
P(semid,0);
printf("add:\n");
a=a+1;
printf("a=%d\n",a);
V(semid,1);
}
}
void* thread2(void *arg)
{
int i=0;
for(i;i<8;i++)
{
P(semid,1);
printf("print:\n");
printf("a=%d\n",a);
V(semid,0);
}
}
int main()
{
pthread_t id1,id2;
int ret1,ret2;
key_t key;
SEM_CTL_UN semctlarg1;
SEM_CTL_UN semctlarg2;
key=1;
semid=semget(key,2,IPC_CREAT|0666);//创建
semctlarg1.val=1;
semctlarg2.val=0;
semctl(semid,0,SETVAL,semctlarg1);//初始化
semctl(semid,1,SETVAL,semctlarg2);
ret1=pthread_create(&id1,NULL,thread1,NULL);
ret2=pthread_create(&id2,NULL,thread2,NULL);
pthread_join(id1,NULL);
pthread_join(id2,NULL);
}
4、实验结果
实验结果截图如下:
图1-1 线程同步
三、实验心得
通过本次实验,我掌握了Linux系统用户界面中键盘命令的使用,熟悉了Linux下的编程环境,进一步理解并掌握了线程的概念,了解了线程同步与通信的主要机制,并能通过信号灯操作实现线程间的同步和互斥。
由于本次实验较为简单,主要目的是熟悉Linux编程环境,所以代码量较小,难度不大,实验过程中没有遇到太大问题。通过实验熟悉了线程的创建和信号灯的设置,为以后的实验打下了基础。
实验二:誊抄实验的进程实现
一、实验目的
在Linux下编程实现誊抄问题,通过多个进(线)程合作将源文件复制到目标文件中。
二、实验内容
1、程序要求
main、get、copy、put四个可执行程序(或线程)。
main:初始化信号灯、缓冲区,创建三个子进程,等待子进程运行结束后做 善后处理;
get : 读源文件,送入缓冲区S;
copy:从S复制信息到T;
put : 将T中信息写入目标文件。
2、运行环境
软件配置(含操作系统版本):ubuntu - 14.10
硬件:PC
3、源程序
源程序:
Get:
#include"touwenjian.h"
int main(void)
{
int i=0;
int shmid1;
char *s,*t,str[]="wangzihao!";
semid = semget(IPCKEY,4,IPC_CREAT|0666);
shmid1 = shmget(SHMKEY1,sizeof(char),IPC_CREAT|0666);
s=(char *)shmat(shmid1,NULL,NULL);
do
{
P(semid,1);
*s=str[i];
printf("get\n");
i++;
V(semid,0);
}while(s[0]!='\0');
}
copy:
#include"touwenjian.h"
int main(void)
{
int j=0;
int shmid1,shmid2;
char *s,*t;
semid = semget(IPCKEY,4,IPC_CREAT|0666);
shmid1 = shmget(SHMKEY1,sizeof(char),IPC_CREAT|0666);
s=(char *)shmat(shmid1,NULL,NULL);
shmid2 = shmget(SHMKEY2,sizeof(char),IPC_CREAT|0666);
t=(char *)shmat(shmid2,NULL,NULL);
do
{
P(semid,0);
P(semid,3);
strcpy(t,s);
printf("copy\n");
V(semid,2);
V(semid,1);
}while(t[0]!='\0');
}
Put:
#include"touwenjian.h"
int main(void)
{
int k=0;
int shmid1,shmid2;
char *s,*t;
semid = semget(IPCKEY,4,IPC_CREAT|0666);
shmid2 = shmget(SHMKEY2,sizeof(char),IPC_CREAT|0666);
t=(char *)shmat(shmid2,NULL,NULL);
do
{
/*if(t[0]=='\0')break;*/
P(semid,2);
if(t[0]!='\0')printf("put---->%c\n",*t);
else printf("put---->\\0\n");
V(semid,3);
}while(t[0]!='\0');
}
头文件:
#include <sys/types.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/shm.h>
#define LOOPS 10
#define IPCKEY (key_t) 0x11
#define SHMKEY1 (key_t)0x222
#define SHMKEY2 (key_t)0x333
void P(int semid,int index);
void V(int semid,int index);
int semid;
void P(int semid,int index)
//对标记符为semid的信号量集 中的第index个
//元素进行P操作(信号量操作要用到semop()函数)
{
struct sembuf sem; //此数据类型在sys/sem.h中定义
sem.sem_num = index;//对信号量集中的第index个元素进行P操作
sem.sem_op = -1; //表示P操作
sem.sem_flg = 0; //操作标记:0或IPC_NOWAIT等
semop(semid,&sem,1); //1:要操作1个信号量
}
void V(int semid,int index)
{
struct sembuf sem;
sem.sem_num =index;
sem.sem_op=1;
sem.sem_flg=0;
semop(semid,&sem,1);
return;
}
4、实验结果
实验结果截图如下:
图2-1 誊抄问题进程实现
三、实验心得
本次实验实现了誊抄问题的进程实现,这是一个经典的进程问题,通过进程合作将源文件复制到目标文件中。
本次实验相较于第一次实验较为复杂,涉及到了文件操作的相关系统调用等操作。实验中共享内存的设置是重点。通过本次实验,我对进程的合作有了更深的了解和认识,掌握了常用文件操作相关系统调用,熟悉了进程的同步于互斥,了解了exec函数组的用法。总而言之,通过本次试验我收获颇丰。
实验三:Linux文件目录操作
一、实验目的
了解并掌握Linux文件目录结构。
二、实验内容
1、程序要求
1)、熟悉Linux文件系统的使用;
2)、了解Linux文件系统目录结构;
3)、编程实现目录查询命令;
功能类似ls -l;
查询指定目录下的文件及子目录信息;
显示文件的类型、大小、时间等信息;
递归显示子目录中的文件信息;
2、运行环境
软件配置(含操作系统版本):ubuntu - 14.10
硬件:PC
3、源程序
源程序:
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
void printdir(char *dir, int depth)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if ((dp=opendir(dir))==NULL){//打开目录不成功
printf("open the file error!\n");
return ;
}
chdir(dir);
char s[1000];
while ((entry=readdir(dp))!=NULL){//读到一个目录项
if (strcmp(entry->d_name,"..")==0||strcmp(entry->d_name, ".")==0){continue;}//跳过
strcpy(s,"./");
strcat(s,entry->d_name);
lstat(s, &statbuf);//读取到了符号链接,lstat读取符号链接本身的状态信息
if (S_ISDIR(statbuf.st_mode)){//权限&类型
int i=0;
for(i=0;i<depth;i++) printf(" ");
printf("|--%s\n", entry->d_name);//文件名
printdir(entry->d_name, depth+1);
}
else
{
int i=0;
for(;i<depth;i++) printf(" ");
printf("|--%s %ld%ld\n", entry->d_name,statbuf.st_size, statbuf.st_ino);
}
}
chdir("../");
closedir(dp);
}
void main(void)
{
char dir[1000];
int depth=0;
scanf("%s",dir);
printdir(dir,depth);
return;
}
4、实验结果
实验结果截图如下:
图3-1 文件目录操作
三、实验心得
通过本次实验,我熟悉了Linux文件系统的使用,了解了Linux文件系统目录结构;实现了查询指定目录下的文件及子目录信息、显示文件的类型、大小、时间等信息、递归显示子目录中的文件信息等功能;学习了Linux文件属性接口和目录文件接口等方面的知识。
文件系统能为用户程序所需要,同时也为操作系统自身需要,它为用户和操作系统提供存储、检测、共享和保护文件的手段,通过本次实验我充分了解了文件系统的重要性,这对我今后的学习有很大的帮助。