fork(), read(), write(), O_APPEND 使用

互应Lab03 fork(), read(), write(), O_APPEND 练习

运行示例程序

fork1.c

linux中fork()函数详解 - 学习记录园 - 博客园

fork调用仅被调用一次,能返回两次,可有三种返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;

创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。

两个进程的变量都是独立的,存在不同的地址中,不是共用的,这点要注意。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void){
    pid_t t;
    // fork is going to create a child process
    t=fork();
    printf("fork returned %d\n",t);
    // exit is to terminate a process and release all the resources
    exit(0);
}

在这里插入图片描述

fork2.c

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>


int main(void){

    pid_t t;

    printf("Original proram, pid = %d\n",getpid());
    t = fork();

    if(t==0){
        printf("In child process, pid = %d, ppid=%d\n",getpid(),getppid());
    }
    else{
        printf("In parent, pid = %d, fork returned = %d\n",
                getpid(),t);
    }
}

结果:

kunling@kunling-VirtualBox:~/Internet_Application/lab03$ ./fork2.out 
Original proram, pid = 3921
In parent, pid = 3921, ppid=3893, fork returned = 3922
kunling@kunling-VirtualBox:~/Internet_Application/lab03$ In child process, pid = 3922, ppid=1110
kunling@kunling-VirtualBox:~/Internet_Application/lab03$ gcc fork2.c -o fork2.out
kunling@kunling-VirtualBox:~/Internet_Application/lab03$ ./fork2.out 
Original proram, pid = 4041
In parent, pid = 4041, fork returned = 4042
kunling@kunling-VirtualBox:~/Internet_Application/lab03$ In child process, pid = 4042, ppid=1110

发现:

在虚拟机上创建新的进程和理论上是不一样的。这个问题需要探讨,可能是因为虚拟机请求主系统创建,那个pid是主系统的?

感觉Ubuntu打开终端老是要搞路径很麻烦,下载nautilus-open-terminal。

ubuntu14设置在当前目录打开终端_xbcReal的博客-CSDN博客

exec1.c

#include<unistd.h>
#include<stdio.h>

int main (void){
    char *arg[] = {"/bin/ls",0};
    /* fork, and exec within child process*/
    if(fork()==0){
        printf("In child process:\n");
        execv(arg[0],arg);
        printf("I will never be called\n");
    }
    printf("Execution continues in parent process\n");
}

输出结果:

kunling@kunling-VirtualBox:~/Internet_Application/lab03$ ./exec1.out 
Execution continues in parent process

kunling@kunling-VirtualBox:~/Internet_Application/lab03$ In child process:
exec1.c   exec1.out  fork1.out    fork2.c~
exec1.c~  fork1.c    fork2.c    fork2.out

lseek1.c

#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h> //exit()

char buf1[] ="abcdefghij";
char buf2[]="ABCDEFGHIJ";
#define FILE_MODE 0644


int main (void){
    int fd;

    if((fd = creat("file.hole",FILE_MODE))<0)
    {
        printf("creat error\n");

        exit(1);
    }
    if(write(fd,buf1,10)!=10){
        printf("buf1 write error\n");
        exit(1);
    }
    /*offset now = 10*/
    if(lseek(fd,40,SEEK_SET)==-1){
    printf("lseek error\n");
    exit(1);
    }
    /*offset now = 40*/
    if(write(fd,buf2,10)!=10){
    printf("buf2 write error\n");
    exit(1)}
    /*offset now = 50*/
    exit(0);
}

输出结果:

kunling@kunling-VirtualBox:~/Internet_Application/lab03$ od -c file.hole 
0000000   a   b   c   d   e   f   g   h   i   j  \0  \0  \0  \0  \0  \0
0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000040  \0  \0  \0  \0  \0  \0  \0  \0   A   B   C   D   E   F   G   H
0000060   I   J
0000062

readwrite1.c

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main(void){
        char quit='.';
        char buf[10];
        int fd;
        if((fd=open("out.out", O_RDWR| O_CREAT))==-1)
        printf("Error in opening\n");

        while(buf[0]!= quit) //遇到‘.'就结束!
        {
             read(0 ,buf, 1);
            write(fd,buf, 1);
            write(1 ,buf, 1);

        }
        close(fd);
}

输出结果:

root@kunling-VirtualBox:/home/kunling/Internet_Application/lab03# ./readwrite1.out 
1234567890
1234567890
qwertyuio
qwertyuio
ff.
ff.root@kunling-VirtualBox:/home/kunling/Internet_Application/lab03# 
root@kunling-VirtualBox:/home/kunling/Internet_Application/lab03# od -c out.out 0000000   1   2   3   4   5   6   7   8   9   0  \n   q   w   e   r   t
0000020   y   u   i   o  \n   f   f   .
0000030

验收O_APPEND的特性

lseek的与O_APPEND的冲突_大海蓝天的专栏-CSDN博客

  • 读取特性

    按照lseek文件指针读取

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h> 

int main(){
    char rbuf1[100];
    int fd;
    int size;
    int currpos;

    //在当前目录创建或者打开文件
    fd = open("testing.txt",O_RDWR| O_APPEND);
    if(fd<0)
        printf("open failed");
    //移动文件指针到开头
    currpos = lseek(fd, 0 , SEEK_SET);

    if(currpos!=0){
    printf("lseek error");
    return -1;
    }

    if(read(fd,rbuf1,sizeof(rbuf1))<0)
    printf("read error!");

    //打印读取到的文件内容
    printf("%s",rbuf1);
    close(fd);
    return 0;
}
  • 写入特性

    lseek文件指针失效,在文件末尾附加。

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include <stdlib.h>

int main(){
    char str_write1[] = "999";
    char str_write2[] = "000";
    char rbuf1[100];
    char rbuf2[100];
    int fd;
    int size;    
       int currpos;

    //在当前目录创建或者打开文件
    fd = open("testing.txt",O_RDWR|O_APPEND|O_CREAT, 0644);
        if(fd<0){
        printf("open and creat failed");
    }

    //移动文件指针到开头
    currpos = lseek(fd, 0 , SEEK_SET);
    if(currpos!=0){
    printf("lseek error");
    return -1;
    }

    //打印当前文件指针位置
    printf("file pointer position: %d\n",currpos);

    //向文件中写入
    size = write(fd, "999", strlen("999"));
    close(fd);
    return 0;
}

动文件指针到开头
currpos = lseek(fd, 0 , SEEK_SET);
if(currpos!=0){
printf(“lseek error”);
return -1;
}

//打印当前文件指针位置
printf("file pointer position: %d\n",currpos);

//向文件中写入
size = write(fd, "999", strlen("999"));
close(fd);
return 0;

}

posted @ 2021-04-03 17:11  無数  阅读(30)  评论(0编辑  收藏  举报