文章目录
前言
本文将介绍一个多进程并发模型的基础应用:如何通过多进程进行一篇文章的复制
一、多进程并发的优缺点
1.多进程并发的优点:
①多进程可以获取并利用更多的系统资源(cpu资源和内存资源)
②如果进程出现阻塞或者挂起,那么可以通过切换时间片交给其他进程(多进程模型其中的一个),那么可以继续执行,提高任务的完成程度
③多进程并发模型的稳定性比较强,各个进程单元相对独立,某个进程异常并不会影响主体任务的执行
2.多进程并发的缺点
①多进程并发模型有较大的调度开销,多进程模型的进程数量不宜过多,进程间的调度开销随着进程数量而增大
②多进程回收是必须做的,但是回收却会影响父进程的其他任务
二、多进程拷贝的流程
1.模块一:参数校验模块(re_parm)
主要负责任务:
(1)检验参数数量是否正确
(2)检验源文件是否存在
(3)进程数量不能小于等于0,并且自己需要设置一个上限
(4)检测用户是否指定了进程数量,如果未指定则需要自己设置一个
2.模块二:分块(block_cur)
主要负责任务:
(1)获取源文件的大小
(2)根据进程数量计算出一块的大小
如果不能整除则+1
(3)返回好计算好的数据量 blocksize
3.模块三:进程创建(process_create)
主要负责任务:
(1)根据进程数量创建出子进程
(2)每个子进程用execl重载拷贝程序来对文件进行拷贝
copy函数需要的参数(src_files, dest_files , blocksize ,pos)
注意: pos是偏移量,是必须要有的,为了防止多进程拷贝重复,需要记录下上一个进程拷贝到哪里。
三: 代码实现:
# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<unistd.h>
# include<sys/types.h>
# include<sys/stat.h>
# include<fcntl.h>
# include<sys/wait.h>
int Re_parm(int parm_num,const char * src_file, int pro_num);//参数校验
int block_cur(const char * src_file, int pro_num);//分块
int process_create(const char * src_file , const char *dest_file,int pro_num,int block_size);//创建父子进程并且execl重载复制功能
void process_wait(void); // 回收模块
int Re_parm(int parm_num,const char * src_file, int pro_num){
if(parm_num <3){
printf("参数数量过少....\n");
exit(1);
}
if(pro_num<=0 || pro_num>=100){
printf("进程数量出现错误....\n");
exit(1);
}
if(access(src_file,F_OK)==-1){
printf("源文件不存在!...\n");
}
return 0;
}
int block_cur(const char * src_file, int pro_num){
int fd;
int file_size;
if((fd=open(src_file,O_RDONLY))==-1){
printf("file open called fail...\n");
exit(0);
}
if((file_size=lseek(fd,0,SEEK_END))==-1){
printf("file seek called fail...\n");
exit(0);
}
close(fd);
if(file_size % pro_num==0 ){
return file_size / pro_num;
}
else return file_size / pro_num +1;
}
void process_wait(void){ //回收模块
pid_t pid;
int status;
while((pid = waitpid(-1,&status,WNOHANG))!=-1){
if(WIFEXITED(status))
printf("Parent Wait zombie Success ,Zombie pid %d ,Child Exitcode %d\n",pid,WEXITSTATUS(status));
if(WIFSIGNALED(status))
printf("Prarent Wait zombie Succeess, Zombie pid %d,signal Number %d\n",pid,WTERMSIG(status));
}
}
int process_create(const char * src_file , const char *dest_file,int pro_num,int block_size){
pid_t pid;
int flag=0;
for(flag;flag<pro_num;flag++){
pid=fork();
if(pid==0)break;
}
if(pid>0){
process_wait();
}
else if(pid ==0){
int pos;
pos = flag * block_size;
char str_blocksize[10];
char str_pos[10];
sprintf(str_blocksize,"%d",block_size);
sprintf(str_pos,"%d",pos);
//子进程用execl进行重载
printf("Copy Process [%d] Copy_pos [%d], Copy_Size [%d]\n",getpid(),pos,block_size);
execl("/home/colin/1213周末班/PROCESS/COPY","COPY",src_file,dest_file,str_blocksize,str_pos,NULL);
}
else {
perror("fork called fail...\n");
exit(-1);
}
return 0;
}
int main(int argc, char *argv[]){
int pronum;
int block_size;
if(argv[3]==0)pronum=5;
else{
pronum = atoi(argv[3]);
}
Re_parm(argc,argv[1],pronum);
block_size = block_cur(argv[1],pronum);
process_create(argv[1],argv[2],pronum,block_size);
return 0;
}
总结
以上就是今天要讲的内容,本文仅仅简单介绍了多进程并发的使用,希望对大家有所帮助,有错误还请指正!