Linux编程基础 5.4.3+6.2.1 学习记录

一.5.4.3文件操作:

1.stat()函数:

        用于获取文件的属性,函数存在于sys/stat.h中,其声明如下:

int stat(const char *path, struct stat *buf);

        参数:path 为文件路径,buf 用于接收获取到的文件属性;文件属性存储在inode中,函数从inode结构体中获取文件信息。

        返回值:调用成功返回0 ;调用失败返回-1并设置errno。

        案例:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(){
    struct stat tempSBuf;
    int tempRet = 2;
    tempRet = stat("a.out", &tempSBuf);
    if(tempRet == -1){
        perror("stat error:");
        exit(1);
    }//of if
    printf("len = %d\n", tempSBuf.st_size);
    return 0;
}

2.access()函数:

        用于测试文件是否拥有某种权限,函数存在于unistd.h中,其声明如下:

int access(const char *pathname, int mode);

        参数:pathname为文件名;mode取值有4个,R_OK,W_OK,X_OK分别用于测试文件是否有读、写、执行权限,最后一个F_OK用于测试文件是否存在。

        返回值:调用成功返回0 ;调用失败返回-1并设置errno。

3.chmod()函数:

        用于修改文件的访问权限,函数存在于sys/stat.h中,其声明如下:

int chmod(const char *path, mode_t mode);

        参数:path为路径名;mode用于传递修改后的权限

        返回值:调用成功返回0 ;调用失败返回-1并设置errno。

4.truncate()函数:

        用于修改文件大小,常用于扩展文件,其功能与lseek函数类似,函数存在于sys/stat.h中,其声明如下:

int truncate(const char *path, off_t length);

        参数:path为路径名,length用于设置文件大小

        返回值:调用成功返回0 ;调用失败返回-1并设置errno。

二.6.2.1创建进程:

1.创建单个进程fock()函数:

        函数执行后,系统会创建一个与原进程几乎相同的进程,之后父子进程都继续执行,该函数存在于unistd.h中,声明如下:

pid_t fork(void);

        无参数输入:

        返回值:调用成功,返回两个值,子进程创建成功后,原程序会被复制,就有了两个fork()函数,父进程的fork函数会返回子进程的pid,子进程的fork函数会返回0;不成功,若子进程创建失败,原程序不会复制,父进程的fork函数返回-1

        案例:使用fork函数创建一个进程,创建成功后父子进程分别执行不同的功能。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
    pid_t tempPid;
    tempPid = fork();
    if(tempPid == -1){
        perror("fork error");
    }else if(tempPid > 0){//parent
        printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
    }else{//child
        printf("child process, pid = %d, ppid = %d\n", getpid(), getppid());
    }//of if
    printf("......finish......");
    return 0;
}//of main

        思考:多次执行案例代码会发现,child process后输出的ppid不等于parent process的pid,而等于1,这是为什么?

        答:因为父进程先于子进程终止,子进程变成“孤儿进程”,后面由init进程来接收,而init进程的pid=1,故而出现上述情况。

2.创建多个进程:

        案例:使用fork函数创建五个进程,创建成功后父子进程分别执行不同的功能。

(1).能否使用简单的循环语句执行fork()达到目的?

for(i = 0; i < 2; i ++)        { tempPid = fork();}

        问题1:每一次循环,进程的总数是当前进程数量的两倍,n次循环则为2^n个进程。NO

        解决方案:在for循环中添加一个判断,若当前进程不是父进程,则跳出循环。

for(i = 0; i < 2; i ++) {

        if((tempPid = fork()) == 0)    break;

}

        问题2:子进程的编号不是递增的,而且终端提示符后面仍然有子进程信息打印,而命令提示符在最后一行的开头闪烁。这是为什么?(提示:父进程和子进程在CPU中的优先级一样。)

        答:在Linux系统中,子进程应由父进程回收,但是当子进程被创建后,它与它的父进程及其它进程共同竞争系统资源,所以父子进程执行的顺序是不确定的,终止的先后顺序也是不确定的,故而呈现出子进程的编号不是递增的这种现象。另外Shell命令提示符也是1个进程,它需要和新建进程一起竞争CPU,主程序结束后,上一个Shell命令结束,shell命令提示符再次被调用,而此时的部分子进程还在竞争CPU,故而呈现终端提示符后面仍然有子进程信息打印这种现象。

        解决方案:利用sleep函数,暂缓进程执行。最终代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
    pid_t tempPid;
    int i;
    for(i = 0; i < 2; i ++){
        if((tempPid = fork()) == 0){
            break;
        }//of if
    }//of for i
    if(tempPid == -1){
        perror("fork error");
    }else if(tempPid > 0){//parent
        sleep(2);
        printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
    }else{//child
         sleep(i);
        printf("I am child process = %d, pid = %d, ppid = %d\n", i + 1, getpid(), getppid());
    }//of if
    printf("......finish......");
    return 0;
}//of main

三.学习总结:

        这次课继续讲解了几个文件操作的相关函数,并重点讲解了fock函数的相关知识和易错点,加深了我们对fock函数的理解和应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值