linux下多进程的文件拷贝与进程相关的一些基础知识
2014-08-09 11:08
381 查看
之前实现了用文件IO的方式可以实现文件的拷贝,那么对于进程而言,我们是否也可以实现呢?
答案是肯定的。
进程资源:
首先我们先回顾一下,进程的运行需要哪些资源呢?其资源包括CPU资源,内存资源,当然还有时间片资源,我们都知道进程是有 栈, 堆, 只读数据段, 数据段(已初始化的全局变量静态变量),bss段(未初始化的),
代码段还有一组寄存器值。
进程命令:
另外我们也可以通过 ps -ef |grep 进程名命令来查看进程号(PID)和父进程号(PPID),之后还可以通过
ps aux |grep 进程名或进程号来查看进程的状态(R,T,S,Z,(+)...).通过 kill -信号的序号或宏 PID来对信号发各种信号,注意这里面的kill可不是杀死进程的意思,我们可以通过给进程发信号来杀死进程kill
-SIGKILL PID ,当然我们可以通过 kill -l 来获取宏名,其次我们通过nice 或renice来给我们的进程设置不同的优先级,等等等等。
进程创建:
我们会用fork函数来创建进程,以前我们都很清除的知道,一个函数只可以返回一个返回值,那么进程创建的函数也只返回一个么?答案是不对的,因为通过fork函数创建的进程,如果成功的话我们向父进程返回子进程的PID号,向子进程返回0,如果创建失败,则向父进程返回-1。创建完子进程后,父进程从fork()的下一条语句开始执行,子进程也是从下一条语句执行么?
是的,因为创建子进程的时候拷贝父进程的pc寄存器值,而pc寄存器的值决定了你的进程是从什么地方开始的,所以当创建完子进程后,我们的子进程的执行与父进程的执行系一样的方式,但是注意他们两个不是一块进行的,也有先后关系,只是先后关系不确定,如果用vfork函数创建进程的话,那么我们的子进程是先进行的。
那么上面说了fork()函数与vfork()函数都可以创建进程,有什么区别呢?
<1>fork创建子进程后,父子进程执行的顺序是不确定的,父子进程的地址空间是独立的。
<2>vfork创建完子进程后,保证子进先执行,父进程在子进程结束,或调用exec函数族后才开始执行,
并且父子进程共享同一地址空间【如果子进程调用了exec函数则子进程会独立出来】。
那么怎样利用进程来进行文件的拷贝呢?以及怎样拷贝呢?具体实现的要求如下,父进程拷贝文件的前一半子进程拷贝文件的后一半,那么效率上面我们肯定比一个进程高得多了,以上就是对进程知识的相关回顾,知识点有了,思路有了,那么剩下的就只是代码实现的问题了,也就是体力劳动了:
请看下面代码的实现:
注:
本程序用到的头文件本人直接封装在了head.h中。如果有哪里需要改进希望留言给我哈
答案是肯定的。
进程资源:
首先我们先回顾一下,进程的运行需要哪些资源呢?其资源包括CPU资源,内存资源,当然还有时间片资源,我们都知道进程是有 栈, 堆, 只读数据段, 数据段(已初始化的全局变量静态变量),bss段(未初始化的),
代码段还有一组寄存器值。
进程命令:
另外我们也可以通过 ps -ef |grep 进程名命令来查看进程号(PID)和父进程号(PPID),之后还可以通过
ps aux |grep 进程名或进程号来查看进程的状态(R,T,S,Z,(+)...).通过 kill -信号的序号或宏 PID来对信号发各种信号,注意这里面的kill可不是杀死进程的意思,我们可以通过给进程发信号来杀死进程kill
-SIGKILL PID ,当然我们可以通过 kill -l 来获取宏名,其次我们通过nice 或renice来给我们的进程设置不同的优先级,等等等等。
进程创建:
我们会用fork函数来创建进程,以前我们都很清除的知道,一个函数只可以返回一个返回值,那么进程创建的函数也只返回一个么?答案是不对的,因为通过fork函数创建的进程,如果成功的话我们向父进程返回子进程的PID号,向子进程返回0,如果创建失败,则向父进程返回-1。创建完子进程后,父进程从fork()的下一条语句开始执行,子进程也是从下一条语句执行么?
是的,因为创建子进程的时候拷贝父进程的pc寄存器值,而pc寄存器的值决定了你的进程是从什么地方开始的,所以当创建完子进程后,我们的子进程的执行与父进程的执行系一样的方式,但是注意他们两个不是一块进行的,也有先后关系,只是先后关系不确定,如果用vfork函数创建进程的话,那么我们的子进程是先进行的。
那么上面说了fork()函数与vfork()函数都可以创建进程,有什么区别呢?
<1>fork创建子进程后,父子进程执行的顺序是不确定的,父子进程的地址空间是独立的。
<2>vfork创建完子进程后,保证子进先执行,父进程在子进程结束,或调用exec函数族后才开始执行,
并且父子进程共享同一地址空间【如果子进程调用了exec函数则子进程会独立出来】。
那么怎样利用进程来进行文件的拷贝呢?以及怎样拷贝呢?具体实现的要求如下,父进程拷贝文件的前一半子进程拷贝文件的后一半,那么效率上面我们肯定比一个进程高得多了,以上就是对进程知识的相关回顾,知识点有了,思路有了,那么剩下的就只是代码实现的问题了,也就是体力劳动了:
请看下面代码的实现:
#include <head.h> int child_copy(int fd_src,int fd_dest,int file_size) { int ret; int n; char buf[1024]; ret = lseek(fd_src,file_size/2,SEEK_SET); if(ret < 0) { perror("Fail to src_file lseek"); exit(EXIT_FAILURE); } ret = lseek(fd_dest,file_size/2,SEEK_SET); if(ret < 0) { perror("Fail to dest_file lseek"); exit(EXIT_FAILURE); } while(1) { n = read(fd_src,buf,sizeof(buf)); if(n == 0) break; write(fd_dest,buf,n); } return 0; } int parent_copy(int fd_src,int fd_dest,int size) { int n; int count = 0; char buf[1024]; while(1) { // lseek(fd_src,0,SEEK_SET); // lseek(fd_dest,0,SEEK_SET); n = read(fd_src,buf,sizeof(buf)); write(fd_dest,buf,n); count += n; if(count >= size/2) break; } return 0; } // ./a.out src_file dest_file int main(int argc, const char *argv[]) { pid_t pid; int file_size; //the size of file int fd_src,fd_dest; struct stat f_info; if(argc < 3) { fprintf(stderr,"Usage :%s argv[1] argv[2]\n",argv[0]); exit(EXIT_FAILURE); } if(stat(argv[1],&f_info) < 0) { fprintf(stderr,"Fail to stat %s: %s",argv[1],strerror(errno)); exit(EXIT_FAILURE); } file_size = f_info.st_size; //get the size of file fd_src = open(argv[1],O_RDONLY);//open the file if(fd_src < 0) { fprintf(stderr,"Fail to open %s : %s\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } fd_dest = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666); if(fd_src < 0) { fprintf(stderr,"Fail to open %s : %s\n",argv[2],strerror(errno)); exit(EXIT_FAILURE); } if(ftruncate(fd_dest,file_size) < 0) //create a empty file { perror("fail to ftruncate"); exit(EXIT_FAILURE); } pid = fork(); if(pid < 0) { fprintf(stderr,"Fail to fork\n",strerror(errno)); exit(EXIT_FAILURE); } if(pid == 0) { close(fd_src); close(fd_dest); fd_src = open(argv[1],O_RDONLY);//open the file again if(fd_src < 0) { fprintf(stderr,"Fail to open %s : %s\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } fd_dest = open(argv[2],O_WRONLY); if(fd_src < 0) { fprintf(stderr,"Fail to open %s : %s\n",argv[2],strerror(errno)); exit(EXIT_FAILURE); } child_copy(fd_src,fd_dest,file_size); } if(pid > 0) { // getchar(); parent_copy(fd_src,fd_dest,file_size); } return 0; }
注:
本程序用到的头文件本人直接封装在了head.h中。如果有哪里需要改进希望留言给我哈
相关文章推荐
- linux性能优化1-进程相关基础知识
- Linux基础学习系列:对于fork()函数的学习,及进程创建相关知识
- Linux基础知识--3.Linux目录和文件相关命令和Linux基础特性2
- Linux基础学习系列:对于fork()函数的学习,及进程创建相关知识
- linux网络编程的一些基础知识--TCP协议相关
- Linux进程的一些基础知识
- linux下关于进程和内存的一些基础知识
- linux文件系统基础知识
- windows程序设计的一些基础知识点—— 进程及其线程
- Java入门--一些JAVA相关的基础知识
- Linux操作系统文件系统基础知识详解
- [转]Linux操作系统文件系统基础知识详解
- linux文件系统基础知识(转帖)
- Linux操作系统文件系统基础知识
- linux文件系统基础知识
- Linux操作系统文件系统基础知识详解
- linux文件系统基础知识
- linux文件系统基础知识
- Linux操作系统文件系统基础知识详解
- Linux操作系统文件系统基础知识详解