#include
#include
off_t lseek(int fd, off_t offset, int whence);
练习1:实现一个Linux系统下计算文件大小的函数使用系统调用
homework
练习2:实现一个带覆盖检查的cp命令
homework
#include
int dup(int oldfd);
int dup2(int oldfd, int newfd);
#include
#include
#include
#include
#include
void init(void){
int fd = open("log.txt",O_RDWR|O_CREAT|O_APPEND,0644);
dup2(fd,1);//如果是0,可以使用gets从日志中读取一行
}
int main(){
init();//init后printf()打印的内容会直接写入log.txt
int fd = dup(2);//fd = 1/2时(STDOUT/STDERR)向fd写入的数据会直接打印
write(fd,"hello",5);
}
练习3 分别使用标准IO与系统IO随机写入100,0000个整数到文件,比较哪一种方法更快,为什么?homework
标准IO使用了缓冲区技术,而每次调用系统IO都要切换用户态和内核态
硬盘上一般会有一些缓冲区以此来提高数据写入效率,操作系统写入数据其实只是写入缓冲区,直到缓冲区满,才排队写入硬盘中
这种操作降低了写入的次数,但是提高了数据写入的延时,导致缓冲区中的数据与磁盘中的内容不同步
注意 此处所讲的缓冲区都指硬盘缓存
void sync(void);
int fsync(int fd);
int fdatasync(int fd);
int fcntl(int fd,int cmd,.../* arg */);
int fcntl(int fd,int cmd, long newfd);
练习1:利用fcntl实现dup,dup2的功能
homework
int fcntl(int fd, int cmd, void/long);
设置或获取文件描述符标志
cmd
目前只能设置FD_CLOEXEC标志位
返回值 0 新进程保持打开状态,1 新进程中关闭该文件描述符
int fcntl(int fd, int cmd, void/long);
F_GETFL
void
O_CREAT,O_EXCL,O_NOCTTY,O_TRUNC
不能获取到F_SETFL
long
O_APPEND,O_ASYNC,O_DIRECT,O_NOATIME,O_NONBLOCK
#include <...>
void file_flags(int fd){
struct Flags{
int flag;
char* name;
}flags[] = {
{O_RDONLY,"O_RDONLY"},
{O_WRONLY,"O_WRONLY"},
{O_RDWR,"O_RDWR"},
{O_APPEND,"O_APPEND"},
{O_ASYNC,"O_ASYNC"},
{O_CLOEXEC,"O_CLOEXEC"},
{O_SYNC,"O_SYNC"}
};
int flags = fcntl(fd,F_GETFL);
for(int i=0;i
int fcntl(int fd, int cmd, struct* flock);
F_GETLK
获取锁的信息F_SETLK
设置锁F_SETLKW
测试锁struct flock {
...
short l_type; /* Type of lock: F_RDLCK,
F_WRLCK, F_UNLCK */
short l_whence; /* How to interpret l_start:
SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Starting offset for lock */
off_t l_len; /* Number of bytes to lock */
pid_t l_pid; /* PID of process blocking our lock
(set by F_GETLK and F_OFD_GETLK) */
...
};
#include <...>
int rlock(int fd){
struct flock lock = {F_RDLOCK,SEEK_SET,0,0,-1};
return fcntl(fd,f_SETLK,&lock);
}
int wlock(int fd){
struct flock lock = {F_WRLOCK,SEEK_SET,0,0,-1};
return fcntl(fd,f_SETLK,&lock);
}
void show_lock(int fd){
struct flock lock = {};
printf("获取锁%s\n",fcntl(fd,F_GETLK,&lock)?"失败":"成功");
if(lock.l_type == F_UNLCK){
printf("无锁\n");
}else{
printf("加锁进程:%d\n",lock.l_pid);
printf("锁类型:%s\n",lock.l_type == F_RDLOCK?"读锁":"写锁");
printf("从文件");
switch(lock.l_whence){
case SEEK_SET:printf("从文件开头");break;
case SEEK_CUR:printf("从当前位置");break;
case SEEK_END:printf("从文件末尾");break;
}
if(lock.l_start > 0){
printf("右移%lu个字节开始",lock.l_start);
}else if(lock.l_start < 0){
printf("左移%lu个字节开始",lock.l_start);
}
if(lock.len){
printf("加锁%lu个字节\n",lock.l_len);
}
else{
printf("加锁到文件末尾\n");
}
}
}
int main(){
int fd = open("a.txt",O_RDWR);
printf("%d\n",rlock(fd));
printf("%d\n",getpid());
getchar();
}