linux文件读写 文件锁、select、poll .
来源:互联网 发布:spss mac安装教程 编辑:程序博客网 时间:2024/06/05 18:48
一、文件锁
文件锁用于多个用户共同使用或操作同一个文件。有读锁的时候可以再加读锁,不能再加写锁。有写锁的时候,不能加任何锁,加读锁时,该描述符必须是读打开,加写锁时,该描述符必须是写打开,且只在进程间有用。
重写的上锁方法
- //lock.c
- int lock_set(int fd,int type){
- struct flock lock;
- lock.l_type=type;
- lock.l_start=0;
- lock.l_whence=SEEK_SET;
- lock.l_len = 0;
- 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);
- }
- lock.l_type = type;
- //此处的F_SETLKW为F_SETLK的阻塞版本,当无法获取锁时进入睡眠等待状态
- if(fcntl(fd,F_SETLKW,&lock)<0){
- printf("Lock failed:type=%d!\n",lock.l_type);
- exit(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("UN lock set by %d\n",getpid());
- break;
- default:
- break;
- }
- }
//lock.cint lock_set(int fd,int type){ struct flock lock; lock.l_type=type; lock.l_start=0; lock.l_whence=SEEK_SET; lock.l_len = 0; 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); } lock.l_type = type; //此处的F_SETLKW为F_SETLK的阻塞版本,当无法获取锁时进入睡眠等待状态 if(fcntl(fd,F_SETLKW,&lock)<0){ printf("Lock failed:type=%d!\n",lock.l_type); exit(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("UN lock set by %d\n",getpid()); break; default: break; }}
上写锁
- #include<stdio.h>
- #include<fcntl.h>
- #include<unistd.h>
- #include"lock.c"
- int main(){
- int fd;
- fd=open("readme",O_RDWR|O_CREAT,0666);
- if(fd<0){
- printf("Open file error\n");
- exit(1);
- }
- lock_set(fd,F_WRLCK);
- getchar();
- lock_set(fd,F_UNLCK);
- getchar();
- return 0;
- }
#include<stdio.h>#include<fcntl.h>#include<unistd.h>#include"lock.c"int main(){ int fd; fd=open("readme",O_RDWR|O_CREAT,0666); if(fd<0){ printf("Open file error\n"); exit(1); } lock_set(fd,F_WRLCK); getchar(); lock_set(fd,F_UNLCK); getchar(); return 0;}
上读锁
- #include<stdio.h>
- #include<fcntl.h>
- #include<unistd.h>
- #include"lock.c"
- int main(){
- int fd;
- fd=open("readme",O_RDWR|O_CREAT,0666);
- if(fd<0){
- printf("Open file error\n");
- exit(1);
- }
- lock_set(fd,F_RDLCK);
- getchar();
- lock_set(fd,F_UNLCK);
- getchar();
- return 0;
- }
#include<stdio.h>#include<fcntl.h>#include<unistd.h>#include"lock.c"int main(){ int fd; fd=open("readme",O_RDWR|O_CREAT,0666); if(fd<0){ printf("Open file error\n"); exit(1); } lock_set(fd,F_RDLCK); getchar(); lock_set(fd,F_UNLCK); getchar(); return 0;}在两个终端中测试:
两个终端可以同时加上读锁。
有一个终端加上读锁,则必须等读锁释放才能加写锁。
有一个终端加写锁必须释放才能加别的锁。
二、多路复用:select、poll
- #include<stdio.h>
- #include<fcntl.h>
- #include<unistd.h>
- #include<memory.h>
- #define MAX(a,b) (a>b?a:b)
- int main(){
- int fd[3];
- char buff[1024];
- int res,max_fd,i,num;
- fd_set insert,temp_insert;
- struct timeval tv;
- fd[0]=0;
- if((fd[1]=open("in1",O_RDONLY|O_NONBLOCK))<0){
- printf("open in1 error!\n");
- return 1;
- }
- if((fd[2]=open("in2",O_RDONLY|O_NONBLOCK))<0){
- printf("open in2 error!\n");
- return 1;
- }
- //选出最大的fd,select()函数用的
- max_fd=MAX(MAX(fd[0],fd[1]),fd[2]);
- //清空fd_set
- FD_ZERO(&insert);
- for(i=0;i<3;i++){
- FD_SET(fd[i],&insert);
- }
- //设置延迟
- tv.tv_sec=60;
- tv.tv_usec=0;
- while(FD_ISSET(fd[0],&insert) || FD_ISSET(fd[1],&insert) || FD_ISSET(fd[2],&insert)){
- temp_insert = insert;
- //select函数会对fd_set产生修改,只保存变化的文件符,所以要用一个temp
- res=select(max_fd+1,&temp_insert,NULL,NULL,&tv);
- switch(res){
- case -1:
- printf("select error!\n");
- return 1;
- break;
- case 0:
- printf("time out\n");
- return 1;
- break;
- default:
- for(i=0;i<3;i++){
- if(FD_ISSET(fd[i],&temp_insert)){
- memset(buff,0,1024);
- num=read(fd[i],buff,1024);
- if(num<0){
- return 1;
- }else if(num == 0){
- close(fd[i]);
- FD_CLR(fd[i],&insert);
- }else{
- if(i == 0){
- if((buff[0] == 'q') || (buff[0] == 'Q')){
- return 0;
- }
- }
- write(STDOUT_FILENO,buff,num);
- }
- }
- }
- }
- }
- }
#include<stdio.h>#include<fcntl.h>#include<unistd.h>#include<memory.h>#define MAX(a,b) (a>b?a:b)int main(){ int fd[3]; char buff[1024]; int res,max_fd,i,num; fd_set insert,temp_insert; struct timeval tv; fd[0]=0; if((fd[1]=open("in1",O_RDONLY|O_NONBLOCK))<0){ printf("open in1 error!\n"); return 1; } if((fd[2]=open("in2",O_RDONLY|O_NONBLOCK))<0){ printf("open in2 error!\n"); return 1; } //选出最大的fd,select()函数用的 max_fd=MAX(MAX(fd[0],fd[1]),fd[2]); //清空fd_set FD_ZERO(&insert); for(i=0;i<3;i++){ FD_SET(fd[i],&insert); } //设置延迟 tv.tv_sec=60; tv.tv_usec=0; while(FD_ISSET(fd[0],&insert) || FD_ISSET(fd[1],&insert) || FD_ISSET(fd[2],&insert)){ temp_insert = insert; //select函数会对fd_set产生修改,只保存变化的文件符,所以要用一个temp res=select(max_fd+1,&temp_insert,NULL,NULL,&tv); switch(res){ case -1: printf("select error!\n"); return 1; break; case 0: printf("time out\n"); return 1; break; default: for(i=0;i<3;i++){ if(FD_ISSET(fd[i],&temp_insert)){ memset(buff,0,1024); num=read(fd[i],buff,1024); if(num<0){ return 1; }else if(num == 0){ close(fd[i]); FD_CLR(fd[i],&insert); }else{ if(i == 0){ if((buff[0] == 'q') || (buff[0] == 'Q')){ return 0; } } write(STDOUT_FILENO,buff,num); } } } } }}
poll用法与select很相似,只是在一些变量上有些不同:
- #include <unistd.h>
- #include <fcntl.h>
- #include <time.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <poll.h>
- #define MAX_BUFFER_SIZE 1024
- #define IO_IN_FILES 3
- #define TIME_DELAY 60000
- int main() {
- struct pollfd fds[IO_IN_FILES];
- char buff[MAX_BUFFER_SIZE];
- int i,res,real_read;
- fds[0].fd=0;
- if((fds[1].fd=open("in1",O_RDONLY|O_NONBLOCK))<0) {
- printf("Open in1 error!\n");
- return 1;
- }
- if((fds[2].fd=open("in2",O_RDONLY|O_NONBLOCK))<0) {
- printf("Open in2 error!\n");
- return 1;
- }
- for(i=0;i<IO_IN_FILES;i++)
- fds[i].events=POLLIN;
- while(fds[0].events||fds[1].events||fds[2].events) {
- res=poll(fds,IO_IN_FILES,TIME_DELAY);
- switch(res) {
- case -1:
- printf("POLL error!\n");
- return 1;
- break;
- case 0:
- printf("Time out!\n");
- return 1;
- break;
- default:
- for(i=0;i<IO_IN_FILES;i++) {
- if(fds[i].revents) {
- memset(buff,0,MAX_BUFFER_SIZE);
- real_read=read(fds[i].fd,buff,MAX_BUFFER_SIZE);
- if(real_read<0){
- printf("Read error!\n");
- return 1;
- } else if (real_read==0) {
- close(fds[i].fd);
- fds[i].events=0;
- } else {
- if (i==0) {
- if((buff[0]=='q')||(buff[0]=='Q'))
- return 0;
- } else {
- write(STDOUT_FILENO, buff,real_read);
- // buff[real_read]='\0';
- // printf("%s",buff);
- }
- }
- }
- }
- }
- }
- return 0;
- }
- linux文件读写 文件锁、select、poll
- linux文件读写 文件锁、select、poll .
- linux文件读写 文件锁、select、poll
- .linux进程知识 程序存储、crontab、fork与vfork、exec、_exit()、wait()与waitpid()、孤儿和僵尸 文件读写 文件锁、select、poll
- 文件操作三(select、poll多路复用)
- linux 系统编程-学习笔记9--线程的同步互斥锁、读写锁/select/poll
- Linux 多进程读写文件 文件锁
- Linux 多进程读写文件 文件锁
- linux select poll
- linux select&poll
- linux之select/poll
- linux select poll epoll
- linux epoll poll select
- linux 文件读写
- linux文件读写浅析
- linux文件读写浅析
- Linux内核读写文件
- Linux内核读写文件
- DIY的MP3,用VS1003做解码器
- Android自动开关机实现
- 查询数据库中有多少个数据表
- 有关“非计算机专业如何转行做程序员”的一点思考
- oracle insert all 和insert first 的区别
- linux文件读写 文件锁、select、poll .
- 读取Android设备的MAC地址
- nodeJS入门例子一—定时器(timers)
- 使用HTTP Client 上传文件到服务器
- asp.net页面生命周期事件执行顺序
- iOS 获取文件属性 NSDirectoryEnumerator 文件大小
- 实现iOS长时间后台的两种方法:Audiosession和VOIP
- FPGA verilog的编程心得---如何写代码减少逻辑单元的使用数量?
- iOS_手机抓包