#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#define BUFFER_SIZE 1024 /*每次读写缓存大小为1KB,大小不同,运行效率不同*/
#define SRC_FILE_NAME "src_file" /*源文件名,建议使用宏定义*/
#define DEST_FILE_NAME "dest_file" //目标文件名*/
#define OFFSET 10240 //复制的数据大小,这里为10KB*/
int main()
{
int src_file,dest_file; /*文件描述符*/
unsigned char buff[BUFFER_SIZE]; /*定义用于缓冲数据的数组*/
int real_read_len; /*read()函数实际读取到的字节*/
/*以只读方式打开源文件*/
src_file = open(SRC_FILE_NAME, O_RDONLY);
/* 以只写方式打开目标文件,若此文件不存在则创建该文件,访问权限为644*/
dest_file = open(DEST_FILE_NAME,O_WRONLY|O_CREAT,0644);
/*如果打开文件出错,则退出程序*/
if(src_file < 0 || dest_file < 0)
{
printf("Open file error\n");
exit(1);
}
/* 将源文件的读/写指针移到下标为0的起始位置*/
lseek(src_file, 0, SEEK_SET); //复制所有
/* 读取源文件的最后2KB数据并写到目标文件中,每次读写1KB*/
while((real_read_len = read(src_file, buff ,sizeof(buff))) > 0)
{
write(dest_file, buff, real_read_len);
}
/* 关闭文件,释放资源*/
close(dest_file);
close(src_file);
return 0;
}
#:gcc copy_file.c -o copy_file
#:./copy_file
#:ls lh dest_file
-rw-r–r-- 1
/*lock_set.c*/
int lock_set(int fd,int type)
{
struct flock old_lock,lock; /*定义flock结构体*/
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 可能在执行完上述判断后被修改了*/
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());/*getpid()用来得到当前的进程号*/
}
break;
case F_WRLCK:
{
printf("Write lock set by %d\n",getpid());
}
break;
case F_UNLCK:
{
printf("Release lock set by %d\n",getpid());
return 1;
}
break;
default:break;
} /*end of switch*/
return 0;
}
首先自己创建一个hello文件
之后对其上写入锁
最后释放写入锁
代码如下:
/*write_lock.c*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/file.h>
#include"lock_set.c"
int main(void)
{
int fd;
/*首先打开文件*/
fd=open("/home/text/3-30/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); /*关闭该文件*/
exit(0);
}
为了更好的验证写入锁是排斥锁
那咱们可以同时打开两个终端,先运行一个./write_lock ,同时去另一个终端上运行./write_lock
第二个终端会提示:write lock already set by 4888
结论:写入锁为互斥锁,同一时刻只能有一个写入锁存在
/*read_lock.c*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/file.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_RDLCK);
getchar(); /*当用户输入任意键后,程序继续执行,否则等待*/
/*给文件解锁*/
lock_set(fd,F_UNLCK);
getchar(); /*当用户输入任意键后,程序继续执行,否则等待*/
close(fd); /*关闭该文件,释放锁*/
exit(0);
}
为了验证写锁为共享锁,咱们也要去打开两个终端,分别去运行./read_lock
。两个终端都能够成功运行,并且获得不同的PID(进程号)
结论:读锁为共享锁,同一时刻可以多可用户读取
1.当在一个终端上运行读锁的,另一个终端上能运行写入锁吗?结果会怎样?