《嵌入式操作系统》实验教学大纲:实验四-Linux进程及文件操作程序设计.doc
《《嵌入式操作系统》实验教学大纲:实验四-Linux进程及文件操作程序设计.doc》由会员分享,可在线阅读,更多相关《《嵌入式操作系统》实验教学大纲:实验四-Linux进程及文件操作程序设计.doc(13页珍藏版)》请在咨信网上搜索。
实验四:Linux进程及文件操作程序设计 第一部分 Linux下文件控制程序设计 一、实验目的 1. 熟悉Linux下文件控制程序设计方法。 2. 掌握利用文件锁实现文件互斥访问程序设计方法。 二、实验设备 装有Red Hat Enterprise Linux 操作系统的PC机 三、实验内容 1、预备知识 当多个用户共同使用、操作一个文件时,Linux 通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。文件锁包括建议性锁和强制性锁。建议性锁要求每个上锁文件的进程都要检查是否有锁存在,并且尊重已有的锁。在一般情况下,内核和系统都不使用建议性锁。强制性锁是由内核执行的锁,当一个文件被上锁进行写入操作的时候,内核将阻止其他任何文件对其进行读写操作。采用强制性锁对性能的影响很大,每次读写操作都必须检查是否有锁存在。 在Linux 中,实现文件上锁的函数有flock和fcntl,其中flock用于对文件施加建议性锁,而fcntl不仅可以施加建议性锁,还可以施加强制锁。同时,fcntl还能对文件的某一记录进行上锁,也就是记录锁。 记录锁又可分为读取锁和写入锁,其中读取锁又称为共享锁,它能够使多个进程都能在文件的同一部分建立读取锁。而写入锁又称为排斥锁,在任何时刻只能有一个进程在文件的某个部分上建立写入锁。当然,在文件的同一部分不能同时建立读取锁和写入锁。 2、fcntl()函数格式 用于建立记录锁的fcntl函数格式如表7.1所示。 表7.1 fcntl函数语法要点 所需头文件 #include <sys/types.h> #include <unistd.h> #include <fcntl.h> 函数原型 int fcnt1(int fd,int cmd,struct flock *lock) 函数传入参数 fd 文件描述符 cmd(命令) F_DUPFD:复制文件描述符 F_GETFL:得到open设置的标志 F_SETFL:改变open设置的标志 F_SETLK:设置lock描述的文件锁 F_SETLKW:这是F_SETLK的阻塞版本 F_GETLK:获取上锁状态。 lock 设置锁参数 函数返回值 成功:0 出错:1 这里,lock的结构如下所示: struct flock { short l_type; off_t l_start; short l_whence; off_t l_len; pid_t l_pid; } lock结构中每个变量的取值含义如表7.2所示。 表7.2 lock结构变量取值 l_type F_RDLCK:读取锁(共享锁) F_WRLCK:写入锁(排斥锁) F_UNLCK:解锁 l_stat 相对位移量(字节) l_whence:相对位移量的起点 SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小。 SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。 SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小。 l_len 加锁区域的长度。 说明 为加锁整个文件,通常的方法是将l_start =0,l_whence=SEEK_SET,l_len=0。 3、实验内容 编程实现使用fcntl 函数为文件上锁的程序。首先创建了一个hello文件,之后对其上写入锁,最后释放写入锁。 编程步骤如下: 1)首先对flock结构体的对应位赋予相应的值。 2)接着调用fcntl函数判断文件是否可以上锁,如果可以,则对其上写入锁(F_SETLKW);如果已有锁存在,则打印锁类型及上锁进程号,并为其上阻塞性写文件锁(F_SETLKW)。 四、实验步骤 1、新建一个子目录。 cd /home mkdir exp5 cd exp5 2、编写实现上述功能的程序代码 编辑上锁子函数:vi lock_set.c 启动vi,然后,按i进入插入状态,并输入源程序。最后,按ESC返回到底行模式,并按:wq存盘退出。 编辑写锁测试主程序:vi write_lock.c启动vi,然后,按i进入插入状态,并输入源程序。最后,按ESC返回到底行模式,并按:wq存盘退出。。 3、编译、调试上述程序。 gcc write_lock.c –o write_lock 4、在PC机端开启两个终端,并且在两个终端上同时运行该程序,以达到多个进程操作一个文件的效果。 新建第一个终端:桌面点右键选择“新建一个终端” 运行write_lock:./ write_lock (第一个终端对hello文件加写锁) 新建第二个终端:桌面点右键选择“新建一个终端” 运行write_lock:./ write_lock (第二个终端对hello文件加写锁,由于第一个写锁还未退出,所以该写锁被阻塞) 在第一个终端按任意键,进行文件解锁。 观察第二个终端,加锁成功。 5、观察实验结果。 首先在终端一上运行./write_lock,然后新建另一个终端并运行./write_lock,由于第一个终端上已经给文件hello上锁了,所以第二个终端程序不能对文件hello上锁而被阻塞。 在第一个终端上,按任意键,使其释放写文件锁。此时,观察终端二可以发现,终端二上的加锁程序完成了加锁任务。 五、实验程序清单 1、实现文件加锁的子程序 /* lock_set.c */ int lock_set(int fd, int type) { struct flock old_lock, lock; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_type = type; lock.l_pid = -1; /* 判断文件是否可以上锁 */ fcntl(fd, F_GETLK, &lock); if (lock.l_type != F_UNLCK) { /* 判断文件不能上锁的原因 */ if (lock.l_type == F_RDLCK) /* 该文件已有读取锁 */ { printf("Read lock already set by %d\n", lock.l_pid); } else if (lock.l_type == F_WRLCK) /* 该文件已有写入锁 */ { printf("Write lock already set by %d\n", lock.l_pid); } } /* l_type 可能已被F_GETLK修改过 */ lock.l_type = type; /* 根据不同的type值进行阻塞式上锁或解锁 */ if ((fcntl(fd, F_SETLKW, &lock)) < 0) { printf("Lock failed:type = %d\n", lock.l_type); return 1; } switch(lock.l_type) { case F_RDLCK: { printf("Read lock set by %d\n", getpid()); } break; case F_WRLCK: { printf("Write lock set by %d\n", getpid()); } break; case F_UNLCK: { printf("Release lock by %d\n", getpid()); return 1; } break; default: break; }/* end of switch */ return 0; } 2、测试用主程序 /* write_lock.c */ #include <unistd.h> #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include "lock_set.c" int main(void) { int fd; /* 首先打开文件 */ fd = open("hello", O_RDWR | O_CREAT, 0644); if(fd < 0) { printf("Open file error\n"); exit(1); } /* 给文件上写入锁 */ lock_set(fd, F_WRLCK); getchar(); /* 给文件解锁 */ lock_set(fd, F_UNLCK); getchar(); close(fd); return 0; } 第二部分: Linux下的多线程程序设计 一、实验目的 1、 通过编写经典的“生产者消费者”问题,进一步熟悉Linux 中多线程编程 2、 掌握用信号量处理线程间的同步互斥的方法。 二、实验设备 装有Red Hat Enterprise Linux 操作系统的PC机 三、实验内容 “生产者消费者”问题描述如下: 有一个有限缓冲区和两个线程:生产者和消费者。他们分别把产品放入缓冲区和从缓冲区中拿走产品。生产者在缓冲区满时必须等待,消费者在缓冲区空时必须等待。同时,要求生产者和消费者不能同时访问缓冲区。它们之间的关系如图1所示: 图1 生产者消费者问题描述 这里要求用有名管道来模拟有限缓冲区,用信号量来解决生产者消费者问题中的同步和互斥问题。 1、信号量的考虑 可以使用3个信号量,其中两个信号量avail和full分别用于解决生产者和消费者线程之间的同步问题,mutex是用于这两个线程之间的互斥问题。其中avail初始化为N(有界缓冲区的空单元数),mutex 初始化为1,full初始化为0。 2、流程图 “生产者消费者”问题的流程流程图如图2所示。 3、编写代码 实验代码中采用的有界缓冲区拥有3个单元,每个单元为5个字节。为了尽量体现每个信号量的意义,在程序中生产过程和消费过程随机(采取0-5s的随机时间间隔)进行的,而且生产者的速度比消费者的速度平均快两倍左右。生产者一次生产一个产品(向缓冲区中放入“hello”字符串),消费者一次消费一个产品。 四、实验步骤 1、新建目录存放所设计的程序。 cd /home mkdir exp8 cd exp8 2、编写“生产者消费者”问题的程序。 输入命令 vi producer-customer.c 启动vi,然后,按i进入插入状态,并输入源程序。最后,按ESC返回到底行模式,并按:wq存盘退出。 3、编译、调试上述程序。 gcc producer-customer.c –o producer-customer –lpthread 4、新建一个终端:桌面点右键选择“新建一个终端” 运行 ./producer-customer 5、观察实验结果。 图2. “生产者消费者”问题的流程流程图 五、参考程序清单 /*producer-customer.c*/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <pthread.h> #include <errno.h> #include <semaphore.h> #include <sys/ipc.h> #include <sys/types.h> #include <sys/stat.h> #define MYFIFO "myfifo" /* 缓冲区有名管道的名字 */ #define BUFFER_SIZE 3 /* 缓冲区的单元数 */ #define UNIT_SIZE 5 /* 每个单元的大小 */ #define RUN_TIME 30 /* 运行时间 */ #define DELAY_TIME_LEVELS 5.0 /* 周期的最大值 */ int fd; time_t end_time; sem_t mutex, full, avail; /* 三个信号量 */ /*生产者线程*/ void *producer(void *arg) { int real_write; int delay_time = 0; while(time(NULL) < end_time) { delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX) / 2.0) + 1; sleep(delay_time); /*P操作信号量avail和mutex*/ sem_wait(&avail); sem_wait(&mutex); printf("\nProducer: delay = %d\n", delay_time); /*生产者写入数据*/ if ((real_write = write(fd, "hello", UNIT_SIZE)) == -1) { if(errno == EAGAIN) { printf("The FIFO has not been read yet.Please try later\n"); } } else { printf("Write %d to the FIFO\n", real_write); } /*V操作信号量full和mutex*/ sem_post(&full); sem_post(&mutex); } pthread_exit(NULL); } /* 消费者线程*/ void *customer(void *arg) { unsigned char read_buffer[UNIT_SIZE]; int real_read; int delay_time; while(time(NULL) < end_time) { delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1; sleep(delay_time); /*P操作信号量full和mutex*/ sem_wait(&full); sem_wait(&mutex); memset(read_buffer, 0, UNIT_SIZE); printf("\nCustomer: delay = %d\n", delay_time); if ((real_read = read(fd, read_buffer, UNIT_SIZE)) == -1) { if (errno == EAGAIN) { printf("No data yet\n"); } } printf("Read %s from FIFO\n", read_buffer); /*V操作信号量avail和mutex*/ sem_post(&avail); sem_post(&mutex); } pthread_exit(NULL); } int main() { pthread_t thrd_prd_id,thrd_cst_id; pthread_t mon_th_id; int ret; srand(time(NULL)); end_time = time(NULL) + RUN_TIME; /*创建有名管道*/ if((mkfifo(MYFIFO, 0777)<0)&&(errno!=EEXIST)) { printf("Cannot create fifo\n"); return errno; } /*打开管道*/ fd = open(MYFIFO, O_RDWR); if (fd == -1) { printf("Open fifo error\n"); return fd; } /*初始化互斥信号量为1*/ ret = sem_init(&mutex, 0, 1); /*初始化avail信号量为N*/ ret += sem_init(&avail, 0, BUFFER_SIZE); /*初始化full信号量为0*/ ret += sem_init(&full, 0, 0); if (ret != 0) { printf("Any semaphore initialization failed\n"); return ret; } /*创建两个线程*/ ret = pthread_create(&thrd_prd_id, NULL, producer, NULL); if (ret != 0) { printf("Create producer thread error\n"); return ret; } ret = pthread_create(&thrd_cst_id, NULL, customer, NULL); if(ret != 0) { printf("Create customer thread error\n"); return ret; } pthread_join(thrd_prd_id, NULL); pthread_join(thrd_cst_id, NULL); close(fd); unlink(MYFIFO); return 0; } switch(lock.l_type) { case F_RDLCK: { printf("Read lock set by %d\n", getpid()); } break; case F_WRLCK: { printf("Write lock set by %d\n", getpid()); } break; case F_UNLCK: { printf("Release lock by %d\n", getpid()); return 1; } break; default: break; }/* end of switch */ return 0; } 2、测试用主程序 /* write_lock.c */ #include <unistd.h> #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include "lock_set.c" int main(void) { int fd; /* 首先打开文件 */ fd = open("hello", O_RDWR | O_CREAT, 0644); if(fd < 0) { printf("Open file error\n"); exit(1); } /* 给文件上写入锁 */ lock_set(fd, F_WRLCK); getchar(); /* 给文件解锁 */ lock_set(fd, F_UNLCK); getchar(); close(fd); return 0; }- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式操作系统 嵌入式 操作系统 实验教学 大纲 实验 Linux 进程 文件 操作 程序设计
咨信网温馨提示:
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【二***】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【二***】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【二***】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【二***】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
关于本文