系统编程-进程-当文件操作遇上fork

我的关联博文:

 

系统编程-进程-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 \n", strlen(string_buf));

	ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
	printf("bytes_done = %ld \n", bytes_done);
	// 创建新文件,向该新文件写入5个字节的字符串。

	off_t offset = lseek(fd, 10, SEEK_END);
	printf("offset = %ld \n", offset);
	// 偏移到文件末尾+10字节位置处,也就是说,
        // 下一次将写入的位置是该文件的第16字节位置处(从文件的第1字节位置开始计算)

	ssize_t add_1_byte = write(fd, &char_H,  1);
	printf("add_1_byte = %ld \n", 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 \n", strlen(string_buf));

	ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
	printf("bytes_done = %ld \n", 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 \n", offset);
		// 偏移到文件末尾+10字节位置处,也就是说,
		// 下一次将写入的位置是该文件的第16字节位置处(从文件的第1字节位置开始计算)


        }else{
		sleep(1);

		ssize_t add_1_byte = write(fd, &char_H,  1);
		printf("add_1_byte = %ld \n", 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 \n", strlen(string_buf));

	ssize_t bytes_done = write(fd, string_buf, strlen(string_buf));
	printf("bytes_done = %ld \n", bytes_done);
	// 创建新文件,向该新文件写入5个字节的字符串。

	off_t offset = lseek(fd, 10, SEEK_END);
	printf("offset = %ld \n", 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 \n", add_1_byte);
		// 在该文件的第16字节处写入一个ascii字符‘H’	

        }else{
		sleep(1);

		ssize_t add_1_byte = write(fd, &char_H,  1);
		printf("add_1_byte = %ld \n", 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中,父子进程操作同一个文件表项,如下图所示

 

 

 

.

posted @ 2021-02-25 16:01  一匹夫  阅读(134)  评论(0编辑  收藏  举报