系统级程序设计第二次作业

一、文件管理:stat、access、chmod、truncate、link函数

1.stat()

#include <sys/stat.h>
int stat(const char *path,struct stat *buf);

功能:用于获取文件的属性;

参数说明:*path:文件路径;

                  *buf:接受获取到的文件属性;文件属性存储在inode中,函数从inode结构体中获取文                     件信息

返回值说明:成功:0

                      不成功:-1并设置errno

【案例1】使用stat函数获取文件属性,并输出文件的大小。
 

#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;
}//of main

运行结果如图:

 2.access()

#include <unistd.h>
int access(const char *pathname, int mode);

功能:用于测试文件是否拥有某种权限;

参数说明:*pathname:文件名;

                  *mode:取值有4个:R_OK,W_OK,X_OK,F_OK;前面3个是测试文件是否有读、写、执行权限,最后一个测试文件是否存在。

返回值说明:成功:0,表示文件存在或具有某种权限。

                      不成功:-1并设置errno

3.chmod()

#include <sys/stat.h>
int chmod(const char *path, mode_t mode);

功能:用于修改文件的访问权限;

参数说明:*path:路径名;

                  *mode:传递修改后的权限。

返回值说明:成功:0,表示文件存在或具有某种权限;

                      不成功:-1并设置errno

4.truncate()

#include <sys/stat.h>
int truncate(const char *path, off_t length);

功能:用于修改文件大小,常用于扩展文件,其功能与lseek函数类似;

参数说明:*path:路径名;

                  *length:设置文件大小。

返回值说明:成功:0

                      不成功:-1并设置errno

二、进程控制:fork()、exec函数族、wait()、exit()

1.1创建进程

#include <unistd.h>
pid_t fork(void);

【案例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......\n");
	return 0;
}//of main

运行结果如下:

 出现的问题:多次执行该程序会发现child process后输出的ppid不等于parent process的pid,而可能等于1。出现这种情况是因为父进程先于子进程终止,子进程变成“孤儿进程”,后面由init进程来接收。


1.2创建多个进程

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

【案例】

#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
		printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
	}else{//child
		printf("I am child process = %d, pid = %d, ppid = %d\n", i + 1, getpid(), getppid());
	}//of if
	printf("......finish......\n");
	return 0;
}//of main

运行结果如下:

 问题及原因

(1)终止的先后顺序随机:子进程的编号不是递增的是因为在Linux系统中,子进程应由父进程回收,但是当子进程被创建后,它与它的父进程及其它进程共同竞争系统资源,所以父子进程执行的顺序是不确定的,终止的先后顺序也是不确定的。

(2)运行完程序后依然闪烁:终端提示符后面仍然有子进程信息打印而命令提示符在最后一行的开头闪烁是因为Shell命令提示符也是一个进程,它需要和新建进程一起竞争CPU。

1.3进程的执行顺序:利用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......\n");
	return 0;
}//of main

运行结果如下:

      心得总结:通过这次的实验让我更深刻地明白了老师上课讲授的进程概念,理解了进程在计算机内部运行的方式和进程之间的关系以及怎样初步操作进程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值