您的位置:首页 > 其它

文件锁以及多路复用方式解决多个用户对一个文件的操作

2017-08-10 20:11 696 查看
一、文件锁用于多个用户共同使用或操作同一个文件。有读锁的时候可以再加读锁,不能再加写锁。有写锁的时候,不能加任何锁,加读锁时,该描述符必须是读打开,加写锁时,该描述符必须是写打开,且只在进程间有用。

使用flock(锁定文件或解除锁定)函数

头文件 #include<sys/file.h>

定义函数 int flock(int fd,int operation);

函数说明 flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作。此函数只能锁定整个文件,无法锁定文件的某一区域。

参数

operation有下列四种情况:

LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。

LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。

LOCK_UN 解除文件锁定状态。

LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。

单一文件无法同时建立共享锁定和互斥锁定,而当使用dup()或fork()时文件描述词不会继承此种锁定。

返回值 返回0表示成功,若有错误则返回-1,错误代码存于errno。

上锁方法:

#include

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;
if(fcntl(fd, F_SETLKW, &lock) < 0)
{
printf("lock failed :type = %d\n", lock.l_type);
}

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
#include
#include
#include
#include "set_lock.h"

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
#include
#include
#include
#include "set_lock.h"

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

select:

#include
#include
#include
#include

#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main()
{
int fd[3];
char buf[1024];
int res;
int max_fd;
int i;
int num;
fd_set insert;
fd_set 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;
}
max_fd = MAX(MAX(fd[0], fd[1]), fd[2]);
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;
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(buf, 0, 1024);
num = read(fd[i], buf, 1024);
if(num < 0)
{
return 1;
}
else if(num == 0)
{
close(fd[i]);
FD_CLR(fd[i], &insert);
}
else
{
if(i == 0)
{
if(buf[0] == 'q' || buf[0] == 'Q')
{
return 0;
}
}
write(STDOUT_FILENO, buf, num);
}
}
}
}
}

}


poll:

#include
#include
#include
#include
#include
#define BUF_SZ 1024
#define IO_IN_FILE 3
#define TIMEDELAY 60000

int main()
{
struct pollfd fd[IO_IN_FILE];
char buf[BUF_SZ];
int res;
int real_read;
int i;

fd[0].fd = 0;

if(fd[1].fd = open("in1", O_RDONLY | O_NONBLOCK) < 0)
{
printf("open in1 error!\n");
return 1;
}
if(fd[2].fd = open("in2", O_RDONLY | O_NONBLOCK) < 0)
{
printf("open in2 error!\n");
return 1;
}
for(i = 0; i < IO_IN_FILE; i++)
{
fd[i].events = POLLIN;
}

while(fd[0].events || fd[1].events || fd[2].events)
{
res = poll(fd, IO_IN_FILE, TIMEDELAY);
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_FILE; i++)
{
if(fd[i].events)
{
memset(buf, 0, BUF_SZ);
real_read = read(fd[i].fd, buf, BUF_SZ);
if(real_read < 0)
{
printf("read error\n");
return 1;
}
else if(real_read == 0)
{
close(fd[i].fd);
fd[i].events = 0;
}
else
{
if(i == 0)
{
if(buf[0] == 'q' || buf[0] == 'Q')
{
return 0;
}
}
write(STDOUT_FILENO, buf, real_read);
}
}
}
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐