系统及程序设计——文件操作与进程管理(work2)

文件操作

stat()
access()
chmod()
truncate()
link()

3.1 stat函数

#include <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;//star类型结构体
	int tempRet = 2;
	tempRet = stat("test.txt", &tempSBuf);
	if(tempRet == -1){//检测文件是否被创建,返回值为-1为创建不成功
		perror("stat error:");
		exit(1);
	}//of if
	printf("len = %d\n", tempSBuf.st_size);//打印出文件的大小,单位为byte
	return 0;
}//of main

 运行结果如上图。

以下关于文件操作的函数功能较为简单,所以在这里就简单的提一下:

3.2 access函数

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

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

  • pathname:文件名;
  • mode:取值有4个:R_OK, W_OK, X_OK, F_OK;前面3个是测试文件是否有读、写、执行权限,最后一个测试文件是否存在。
  • 返回值的功能与上述函数类似。

3.3 chmod函数

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

功能:用于修改文件的访问权限;
参数说明:

  • path:路径名;
  • mode:传递修改后的权限。
  • mode与3.2的mode是一样的。

3.4 truncate函数

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


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

path:路径名;
length:设置文件大小。
 

3.1:进程管理-1

以下是关于进程控制的四个函数:

fork()
exec函数族
wait()
exit()

1.1创建进程

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

功能:创建进程;函数执行后,系统会创建一个与原进程几乎相同的进程,之后父子进程都继续执行,如图所示:

在这里插入图片描述

 

图 fork函数创建子进程

参数说明:无

返回值说明:

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

接下来我们用fork函数创建一个进程,创建成功后父子进程分别执行不同的功能。

代码如下:

test_fork.c
#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

 【思考 1】多次执行test_fork会发现,child process后输出的ppid不等于parent process的pid,而等于1。请说明原因。

在多次执行文件创建多个进程之后,因为容纳进程数量有限,所以在有许多进程时,系统会回收一定量的进程,当把父进程回收之后,之前剩下的进程变成了孤儿进程,有init进程来接收,其ppid就变成了1

创建多个进程:

在这里插入图片描述

在这里插入图片描述

 

若只是简单的讲temPid=fork()进行循环,每次调用fork函数,系统会复制原程序
i=0,第一次循环,会有两份test_fork文件
i=1,第二次循环,第一份test_fork文件又会有两份test_fork文件,第二份test_fork文件也会有两份
每一次循环,进程的总数是当前进程数量的两倍,2次循环则为2 2 = 4 2^2 = 42 
2
 =4个进程。
这不是我们一开始的目的,我们只想要让父进程来进行fork复制,所以我们在循环的时候要进行条件判断,这是又要用到fork函数的返回值来进行了:

test_fork2.c
#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......");
	return 0;
}//of main

执行结果如下:

我们可以看到,子进程的编号并非我们想象中的递增的这是因为在执行过程中,进程的优先级相同,在Linux系统中,子进程应由父进程回收,但是当子进程被创建后它与它的父进程及其它进程共同竞争系统资源,父子进程会发生抢占现象,执行与终止先后顺序也有差别,所以进程的复制不是按着我们想象中那样顺序执行的 

终端提示符后面仍然有子进程信息打印,而命令提示符在最后一行的开头闪烁。
这是为什么?

这是因为Shell命令提示符也是1个进程,它需要和新建进程一起竞争CPU,所以才有了开头闪烁现象

所以我们如何应当让进程顺序顺序执行,这里可以想到的是用sleep函数,在创建之后睡上一段时间,避免发生互相抢占资源的情况,且父进程与子进程的睡眠时间应该有所不同,以此来控制执行顺序

test_fork3.c
#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

代码执行如下:

 总结:

fork()函数用于创建与当前进程一个一样的进程,除了进程号不同之外(父子关系),之后两个进程都继续执行,fork函数执行成功返回两个值,子进程创建成功后,原程序会被复制,就有了两个fork函数。父进程的fork函数会返回子进程的pid,子进程的fork函数会返回0,我们用返回值来判断该进程是父进程还是子进程,getpid()函数可以直接返回当前进程的进程号,getppid则是查看此进程的父进程的进程号。

当我们想要创建多个进程时,根据我们的目的来设置创建进程的条件,不进行条件设置,那么进程的复制就是指数型复制的,就会出现如上文之中所给出的实例一样的复制情况,所以灵活运用fork函数返回值来复制进程。

若想要顺序执行进程,那么一定需要加以控制,设置进程优先级难度太高了且不方便,能想到的简单一点的方法就是使用sleep函数,对父进程或子进程进行不同程度的休眠,以此来达到我们的目的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值