我的关联博文:
系统编程-进程-fork深度理解、vfork简介
系统编程-进程-先后fork或open一个文件的区别
test1: lseek基本使用
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
char string_buf[] = "hello";
char char_H = 'H';
int main(){
int fd = open("file.txt", O_CREAT|O_RDWR|O_TRUNC, S_IRWXU);
printf("sizeof(string_buf) = %ld
", strlen(string_buf));
ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
printf("bytes_done = %ld
", bytes_done);
// 创建新文件,向该新文件写入5个字节的字符串。
off_t offset = lseek(fd, 10, SEEK_END);
printf("offset = %ld
", offset);
// 偏移到文件末尾+10字节位置处,也就是说,
// 下一次将写入的位置是该文件的第16字节位置处(从文件的第1字节位置开始计算)
ssize_t add_1_byte = write(fd, &char_H, 1);
printf("add_1_byte = %ld
", add_1_byte);
// 在该文件的第16字节处写入一个ascii字符‘H’
close(fd);
return 0;
}
探究父子进程的文件描述符、文件表项、I节点,
以lseek+fork实验为切入点进行分析。
实验思路:
做两个实验,一是先fork,父进程先lseek后, 子进程才write,观察子进程写入该文件的偏移在哪。
再一个实验是,先lseek,然后才fork。
test2
探究父子进程的文件描述符、文件表项、I节点
以lseek+fork实验为切入点进行分析
实验思路:先fork,父进程先lseek后, 子进程才write,观察子进程写入该文件的偏移在哪。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
char string_buf[] = "hello";
char char_H = 'H';
int main(){
int fd = open("file.txt", O_CREAT|O_RDWR|O_TRUNC, S_IRWXU);
printf("sizeof(string_buf) = %ld
", strlen(string_buf));
ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
printf("bytes_done = %ld
", bytes_done);
// 创建新文件,向该新文件写入5个字节的字符串。
pid_t pid = fork();
if(pid < 0){
perror("fork ");
}else if( pid > 0){
off_t offset = lseek(fd, 10, SEEK_END);
printf("offset = %ld
", offset);
// 偏移到文件末尾+10字节位置处,也就是说,
// 下一次将写入的位置是该文件的第16字节位置处(从文件的第1字节位置开始计算)
}else{
sleep(1);
ssize_t add_1_byte = write(fd, &char_H, 1);
printf("add_1_byte = %ld
", add_1_byte);
// 在该文件的第16字节处写入一个ascii字符‘H’
}
close(fd);
return 0;
}
编译运行:
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当
文件操作遇上fork# gcc test.c
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当
文件操作遇上fork# ./a.out
sizeof(string_buf) = 5
bytes_done = 5
offset = 15
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当
文件操作遇上fork# add_1_byte = 1
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当
文件操作遇上fork# hexdump -C -n 100 file.txt
00000000 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 48 |hello..........H|
00000010
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork#
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork#
实验现象: 父进程在fork前打开了文件,父进程先执行lseek, 子进程延时1秒后才执行写文件,则会受父进程刚才的lseek操作影响。
小结: 文件偏移量这一信息记录在内核的文件表项中,父子进程有自己独立的文件描述符表,但是共享文件表项和I节点。
本实验父子进程实际上操作的是同一个文件表项,所以才产生了这种现象。
test3
探究父子进程的文件描述符、文件表项、I节点
以lseek+fork实验为切入点进行分析
实验思路:先lseek,然后才fork...
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
char string_buf[] = "hello";
char char_H = 'H';
char char_L = 'L';
int main(){
int fd = open("file.txt", O_CREAT|O_RDWR|O_TRUNC, S_IRWXU);
printf("sizeof(string_buf) = %ld
", strlen(string_buf));
ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
printf("bytes_done = %ld
", bytes_done);
// 创建新文件,向该新文件写入5个字节的字符串。
off_t offset = lseek(fd, 10, SEEK_END);
printf("offset = %ld
", offset);
// 偏移到文件末尾+10字节位置处,也就是说,
// 下一次将写入的位置是该文件的第16字节位置处(从文件的第1字节位置开始计算)
pid_t pid = fork();
if(pid < 0){
perror("fork ");
}else if( pid > 0){
ssize_t add_1_byte = write(fd, &char_L, 1);
printf("add_1_byte = %ld
", add_1_byte);
// 在该文件的第16字节处写入一个ascii字符‘H’
}else{
sleep(1);
ssize_t add_1_byte = write(fd, &char_H, 1);
printf("add_1_byte = %ld
", add_1_byte);
// 在该文件的第16字节处写入一个ascii字符‘H’
}
close(fd);
return 0;
}
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork# gcc test.c
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork# ./a.out
sizeof(string_buf) = 5
bytes_done = 5
offset = 15
add_1_byte = 1
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork# add_1_byte = 1
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork# hexdump -C -n 100 file.txt
00000000 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 4c |hello..........L|
00000010 48 |H|
00000011
root@lmw-virtual-machine:/home/lmw/MINE/Linux_C_exercise/fork/当文件操作遇上fork#
小结: 同上一个实验。即:
文件偏移量这一信息记录在内核的文件表项中,父子进程有自己独立的文件描述符表,但是共享文件表项和I节点。
本实验父子进程实际上操作的是同一个文件表项,所以才产生了这种现象。
内核文件结构:
本博文test2、test3中,父子进程操作同一个文件表项,如下图所示
.