昨天練習多進程,寫了多進程拷貝的代碼,在此記錄下。
多進程拷貝就是用多個進程對同一篇文檔進行拷貝,若文檔有len字節,則每個字節只需要拷貝
len/n個字節,但並不一定完全整除,我們只要讓最後一個子進程負責剩餘的字節就好。
因爲進程之間是以時間片輪轉的方式搶佔CPU,所以只是理論上的比單進程快,在此只是作爲練習。
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/mman.h>
#include<sys/types.h>
#include<stdlib.h>
#include<sys/fcntl.h>
#include<sys/stat.h>
int main(void)
{
pid_t pid;
int fd=open("/home/ubuntu/text/a.txt",O_RDWR);//用讀寫的方式打開文檔
if(fd == -1)//若打開失敗,打印錯誤。
{
perror("open_fd error:");
exit(1);
}
struct stat statbuff;
int set=stat("/home/ubuntu/text/a.txt",&statbuff);//將inode節點信息存儲在statbuff
int num=statbuff.st_size;//文件大小
if(set == -1)//發生錯誤打印
{
perror("stat error:");
exit(1);
}
int fd_1=open("/home/ubuntu/text/b.txt",O_RDWR|O_CREAT|O_TRUNC,0644);
ftruncate(fd_1,statbuff.st_size);//將文件大小設爲statbuff.st_size
if(fd_1 == -1){//出錯打印錯誤信息
perror("open_fd_1 error:");
exit(1);
}
char *mm=mmap(NULL,statbuff.st_size,PROT_READ,MAP_SHARED,fd,0);//mmap建立映射區
if(mm == MAP_FAILED){//發生錯誤打印錯誤信息
perror("mm_mmap error:");
exit(1);
}
close(fd);//關閉文件
char *mm_1=mmap(NULL,statbuff.st_size,PROT_WRITE,MAP_SHARED,fd_1,0);//mmap建立映射區
if(mm_1 == MAP_FAILED)//出錯打印錯誤信息
{
perror("mm_1_mmap error:");
exit(1);
}
close(fd_1);//關閉文件
int i;
for(i=0;i<5;i++){//循環創建子進程
pid=fork();
if(pid == -1){
perror("fork error:");
exit(1);
}
else if(pid == 0)
{
if(i!=4)
{
memcpy(mm_1+(statbuff.st_size/5)*i,mm+(statbuff.st_size/5)*i,statbuff.st_size/5);//子進程進行文檔拷貝
}
else{
memcpy(mm_1+(statbuff.st_size/5)*i,mm+(statbuff.st_size/5)*i,num-(statbuff.st_size/5)*i);//最後一個子進程收尾
}
break;
}
}
int a=munmap(mm,num);//關閉mm指向的映射區
if(a == -1){//出錯打印出錯信息
perror("munmap_mm error:");
exit(1);
}
int b=munmap(mm_1,num);//關閉mm_1指向的映射區
if(b == -1){//出錯打印出錯信息
perror("munmap_mm_1 error:");
exit(1);
}
pid_t vis=0;
if(pid>0){//回收所有子進程
while(vis!=-1){
vis=wait(NULL);
}
}
return 0;
}