文件的读写与上锁.docx
- 文档编号:24508230
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:12
- 大小:18.64KB
文件的读写与上锁.docx
《文件的读写与上锁.docx》由会员分享,可在线阅读,更多相关《文件的读写与上锁.docx(12页珍藏版)》请在冰豆网上搜索。
文件的读写与上锁
1.实验目的
通过编写文件读写及上锁的程序,进一步熟悉Linux中文件I/O相关的应用开发,并且熟练掌握open()、read()、write()、fcntl()等函数的使用。
2.实验内容
在Linux中FIFO(先进先出)是一种进程间的管道通信机制。
本实验通过使用文件操作,仿真FIFO结构以及生产者-消费者运行模型。
3.实验步骤
(1)流程图
该实验流程图如图所示
(2)程序说明
本实验需要打开两个虚拟终端,分别运行生产者程序(producer)和消费者程序(customer)。
此时两个进程同时对同一个文件进行读写操作。
因为这个文件是临界资源,所以可以使用文件锁机制保证两个进程对文件的访问都是原子操作。
先启动生产者进程,它负责创建仿真FIFO结构文件(实际是一个普通文件)并投入生产,就是按照给定的时间间隔,向FIFO文件写入自动生成的字符(在程序中用宏定义选择使用数字还是使用英文字符),生产周期以及要生产的资源数通过参数传递给进程(默认生产周期1S,要生产的资源数为10个字符)。
后启动的消费者进程按照给定的数目进行消费,首先从文件中读取相应数目的字符并在屏幕显示,然后从文件中删除刚才消费过的数据。
为了仿真FIFO结构,此时需要使用两次复制来实现文件内容的偏移。
每次消费的资源数通过参数传递给进程,默认值为10个字符。
(3)代码
/**/
intlock_set(intfd,inttype)
{
structflockold_lock,lock;
=SEEK_SET;
=0;
=0;
=type;
=-1;
/*判断文件是否可以上锁*/
fcntl(fd,F_GETLK,&lock);
if!
=F_UNLCK)
{
/*判断文件不能上锁的原因*/
if==F_RDLCK)/*该文件已有读取锁*/
{
printf("Readlockalreadysetby%d\n",;
}
elseif==F_WRLCK)/*该文件已有写入锁*/
{
printf("Writelockalreadysetby%d\n",;
}
}
/*l_type可能已被F_GETLK修改过*/
=type;
/*根据不同的type值进行阻塞式上锁或解锁*/
if((fcntl(fd,F_SETLKW,&lock))<0)
{
printf("Lockfailed:
type=%d\n",;
return1;
}
switch
{
caseF_RDLCK:
{
printf("Readlocksetby%d\n",getpid());
}
break;
caseF_WRLCK:
{
printf("Writelocksetby%d\n",getpid());
}
break;
caseF_UNLCK:
{
printf("Releaselockby%d\n",getpid());
return1;
}
break;
default:
break;
}/*endofswitch*/
return0;
}
本实验中的生产者程序的源代码如下所示,其中用到的lock_set()函数。
/**/
#include<>
#include<>
#include<>
#include<>
#include<>
#include""
#defineMAXLEN10/*缓冲区大小最大值*/
#defineALPHABET1/*表示使用英文字符*/
#defineALPHABET_START'a'/*头一个字符,可以用'A'*/
#defineCOUNT_OF_ALPHABET26/*字母字符的个数*/
#defineDIGIT2/*表示使用数字字符*/
#defineDIGIT_START'0'/*头一个字符*/
#defineCOUNT_OF_DIGIT10/*数字字符的个数*/
#defineSIGN_TYPEALPHABET/*本实例选用英文字符*/
constchar*fifo_file="./myfifo";/*仿真FIFO文件名*/
charbuff[MAXLEN];/*缓冲区*/
/*功能:
生产一个字符并写入到仿真FIFO文件中*/
intproduct(void)
{
intfd;
unsignedintsign_type,sign_start,sign_count,size;
staticunsignedintcounter=0;
/*打开仿真FIFO文件*/
if((fd=open(fifo_file,O_CREAT|O_RDWR|O_APPEND,0644))<0)
{
printf("Openfifofileerror\n");
exit
(1);
}
sign_type=SIGN_TYPE;
switch(sign_type)
{
caseALPHABET:
/*英文字符*/
{
sign_start=ALPHABET_START;
sign_count=COUNT_OF_ALPHABET;
}
break;
caseDIGIT:
/*数字字符*/
{
sign_start=DIGIT_START;
sign_count=COUNT_OF_DIGIT;
}
break;
default:
{
return-1;
}
}/*endofswitch*/
sprintf(buff,"%c",(sign_start+counter));
counter=(counter+1)%sign_count;
lock_set(fd,F_WRLCK);/*上写锁*/
if((size=write(fd,buff,strlen(buff)))<0)
{
printf("Producer:
writeerror\n");
return-1;
}
lock_set(fd,F_UNLCK);/*解锁*/
close(fd);
return0;
}
intmain(intargc,char*argv[])
{
inttime_step=1;/*生产周期*/
inttime_life=10;/*需要生产的资源数*/
if(argc>1)
{
sscanf(argv[1],"%d",&time_step);
}
if(argc>2)
{
sscanf(argv[2],"%d",&time_life);
}
while(time_life--)
{
if(product()<0)
{
break;
}
sleep(time_step);
}
exit(EXIT_SUCCESS);
}
本实验中的消费者程序的源代码如下所示。
/**/
#include<>
#include<>
#include<>
#include<>
#defineMAX_FILE_SIZE100*1024*1024/*100M*/
constchar*fifo_file="./myfifo";/*仿真FIFO文件名*/
constchar*tmp_file="./tmp";/*临时文件名*/
/*资源消费函数*/
intcustoming(constchar*myfifo,intneed)
{
intfd;
charbuff;
intcounter=0;
if((fd=open(myfifo,O_RDONLY))<0)
{
printf("Functioncustomingerror\n");
return-1;
}
printf("Enjoy:
");
lseek(fd,SEEK_SET,0);
while(counter { while((read(fd,&buff,1)==1)&&(counter { fputc(buff,stdout);/*消费就是在屏幕上简单的显示*/ counter++; } } fputs("\n",stdout); close(fd); return0; } /*功能: 从sour_file文件的offset偏移处开始将count字节大小的数据拷贝到dest_file文件*/ intmyfilecopy(constchar*sour_file,constchar*dest_file,intoffset, intcount,intcopy_mode) { intin_file,out_file; intcounter=0; charbuff_unit; if((in_file=open(sour_file,O_RDONLY|O_NONBLOCK))<0) { printf("Functionmyfilecopyerrorinsourcefile\n"); return-1; } if((out_file=open(dest_file, O_CREAT|O_RDWR|O_TRUNC|O_NONBLOCK,0644))<0) { printf("Functionmyfilecopyerrorin destinationfile: "); return-1; } lseek(in_file,offset,SEEK_SET); while((read(in_file,&buff_unit,1)==1)&&(counter { write(out_file,&buff_unit,1); counter++; } close(in_file); close(out_file); return0; } /*功能: 实现FIFO消费者*/ intcustom(intneed) { intfd; /*对资源进行消费,need表示该消费的资源数目*/ customing(fifo_file,need); if((fd=open(fifo_file,O_RDWR))<0) { printf("Functionmyfilecopyerrorinsource_file: "); return-1; } /*为了模拟FIFO结构,对整个文件内容进行平行移动*/ lock_set(fd,F_WRLCK); myfilecopy(fifo_file,tmp_file,need,MAX_FILE_SIZE,0); myfilecopy(tmp_file,fifo_file,0,MAX_FILE_SIZE,0); lock_set(fd,F_UNLCK); unlink(tmp_file); close(fd); return0; } intmain(intargc,char*argv[]) { intcustomer_capacity=10; if(argc>1)/*第一个参数指定需要消费的资源数目,默认值为10*/ { sscanf(argv[1],"%d",&customer_capacity); } if(customer_capacity>0) { custom(customer_capacity); } exit(EXIT_SUCCESS); } 4、实验结果 此实验的运行结果如下所示。 实验结果会和这两个进程运行的具体过程相关。 终端一: #./producer115/*生产周期为1S,需要生产的资源数为20个*/ Writelocksetby11867 Releaselockby11867 …… 终端二: #./customer5/*需要消费的资源数为5个*/ Enjoy: abcde Writelocksetby11879 Releaselockby11879
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 文件 读写 上锁
![提示](https://static.bdocx.com/images/bang_tan.gif)