zoukankan      html  css  js  c++  java
  • 系统编程-进程-当文件操作遇上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 
    ", 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中,父子进程操作同一个文件表项,如下图所示

    .

    /************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
  • 相关阅读:
    Hyperledger Fabric的容灾备份及恢复方法
    Sentinel使用
    Fabric1.4 架构和原理
    centos开放指定端口
    Python使用ProtoBuffer
    C++动态创建对象
    Shell笔记
    Go语言基础(二)
    Go语言基础(一)
    git常用命令
  • 原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/14447444.html
Copyright © 2011-2022 走看看