您的位置:首页 > 其它

多进程和多线程文件拷贝

2016-05-10 12:14 225 查看
1. 线程与进程的异同点

A.相同点

1):  比如都有自己在系统中唯一标识ID,一组寄存器(pc指针),状态(6种),调度优先级以及所要遵循的调度策略。

2):  每个进程都有一个进程控制块,线程也拥有一个线程控制块(在Linux内核,线程控制块与进程控制块用同一个结         构体描述,即struct  task_struct),这个控制块包含线程的一些属性信息,操作系统使用这些属性信息来描述线             程。

3):  线程和子进程的创建者可以在线程和子进程上实行某些控制,比如,创建者可以取消、挂起、继续和修改线程和         子进程的优先级。

B.不同点

1): 主要区别:每个进程都拥有自己的地址空间,但线程没有自己独立的地址空间,但是线程栈是线程专属的,而是运         行在一个进程里的所有线程共享该进程的整个虚拟地址空间。

2):  线程的上下文切换时间开销比进程上下文切换时间开销要小的多

3):  线程的创建开销远远小于进程的创建

4): 子进程拥有父进程的地址空间和数据段的拷贝,因此当子进程修改它的变量和数据时,它不会影响父进程中的数         据,但线程可以直接访问它进程中的数据段。

5):  进程之间通讯必须使用进程间通讯机制,但线程可以与进程中的其他线程直接通讯

6):  线程可以对同一进程中的其他线程实施大量控制,但进程只能对子进程实施控制

7):  改变主线程的属性可能影响进程中其他的线程,但对父进程的修改不影响子进程

2. 多进程文件拷贝程序:

<pre name="code" class="cpp">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

int copy_file_init(const char *src_file,const char *dest_file)
{
int fd_src;
int fd_dest;
int src_file_len;

fd_src = open(src_file,O_RDONLY);
if(fd_src < 0){
fprintf(stderr,"Fail to open %s : %s\n",src_file,strerror(errno));
exit(EXIT_FAILURE);
}

src_file_len = lseek(fd_src,0,SEEK_END);

fd_dest = open(dest_file,O_WRONLY | O_TRUNC | O_CREAT,0666);
if(fd_dest < 0){
fprintf(stderr,"Fail to open %s : %s\n",dest_file,strerror(errno));
exit(EXIT_FAILURE);
}

close(fd_src);
close(fd_dest);

return src_file_len;
}

int copy_file(const char *src_file,const char *dest_file,int postion,int len)
{
int n;
int fd_src;
int fd_dest;
int count = 0;
char buf[1024];

fd_src = open(src_file,O_RDONLY);
if(fd_src < 0){
fprintf(stderr,"Fail to open %s : %s\n",src_file,strerror(errno));
exit(EXIT_FAILURE);
}

fd_dest = open(dest_file,O_WRONLY);
if(fd_dest < 0){
fprintf(stderr,"Fail to open %s : %s\n",dest_file,strerror(errno));
exit(EXIT_FAILURE);
}

lseek(fd_src,postion,SEEK_SET);
lseek(fd_dest,postion,SEEK_SET);

while(1){
n = read(fd_src,buf,sizeof(buf));
if(n <= 0){
break;
}

n = write(fd_dest,buf,n);
if(n <= 0){
break;
}

count += n;

if(count >= len){
break;
}
}

close(fd_src);
close(fd_dest);

return count;
}

void process_copy_file(const char *src_file,const char *dest_file,int src_file_len,int precess_num)
{
int n;
int m=0;
pid_t pid;

pid = fork();
if(pid < 0){
perror("Fail to fork");
exit(EXIT_FAILURE);
}

if(pid == 0){
n = copy_file(src_file,dest_file,src_file_len/2,(src_file_len - src_file_len / 2));
printf("Child process copy %d bytes!\n",n);
}

if(pid > 0){
n = copy_file(src_file,dest_file,0,src_file_len / 2);
printf("Parent process copy %d bytes!\n",n);
}

while(precess_num > 0){
pid = fork();
if(pid < 0){
perror("Fail to fork");
exit(EXIT_FAILURE);
}
else{
n--;
}
if
}

return ;
}

//./a.out src_file dest_file
int main(int argc, const char *argv[])
{
int src_file_len;

if(argc < 3){
fprintf(stderr,"Usage : %s <src file> <dest file>!\n",argv[0]);
exit(EXIT_FAILURE);
}

src_file_len = copy_file_init(argv[1],argv[2]);
process_copy_file(argv[1],argv[2],src_file_len);
exit(EXIT_SUCCESS);

}





3. 多线程文件拷贝程序:

#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

//pthread_mutex_t lock;
struct args{
char src_file[128];
char des_file[128];
int position;
int len;
};

int get_filelen(const char *src_file)
{
int len;
FILE *fp;
fp = fopen(src_file,"r");
fseek(fp,0,SEEK_END);
len = ftell(fp);
rewind(fp);
return len;
}

void init_args(struct args *args ,const char *src_file,const char *des_file,int pos,int len)
{
strcpy(args->src_file, src_file);
strcpy(args->des_file, des_file);
args->position = pos;
args->len = len;
}

void *copy_file(void *arg)
{
// pthread_mutex_lock(&lock);
int n = 0;
int ret;
int count = 0;
int read_len = 0;
char buf[4096];
FILE *fp1,*fp2;
struct args *p = (struct args*)arg;
fp1 = fopen(p->src_file,"r");
if(fp1 == NULL){
fprintf(stderr,"fopen file %s fail:%s\n",p->src_file,strerror(errno));
exit(EXIT_FAILURE);
}

fp2 = fopen(p->des_file,"a");
if(fp2 == NULL){
fprintf(stderr,"fopen file %s fail:%s\n",p->des_file,strerror(errno));
exit(EXIT_FAILURE);
}

fseek(fp1,p->position,SEEK_SET);
fseek(fp2,p->position,SEEK_SET);
printf("p->position=%d,p->len=%d\n",p->position,p->len);
read_len = p->len > 4096?4096:p->len;

while(1){
if(count >= p->len){
break;
}
printf("read_len=%d\n",read_len);
n = fread(buf,sizeof(buf[0]),read_len,fp1);
if(n <= 0){
printf("fread over: %d\n",n);
break;
}
printf("n=%d\n",n);
ret = fwrite(buf,sizeof(buf[0]),n,fp2);
if(ret <= 0){
printf("fwrite over\n");
break;
}
count += n;
}
printf("write %d bytes to des file\n",count);

fclose(fp1);
fclose(fp2);
// pthread_mutex_unlock(&lock);
}

int main(int argc, const char *argv[])
{
int ret;
int len;
int position;
struct args args1,args2;
pthread_t tid1,tid2;

//pthread_mutex_init(&lock,NULL);

if(argc < 3){
fprintf(stderr,"Usage: %s <filename> <filename>\n",argv[0]);
exit(EXIT_FAILURE);
}

len = get_filelen(argv[1]);
position = len / 2;
init_args(&args1,argv[1],argv[2],0,position);
init_args(&args2,argv[1],argv[2],position,len-position);
fprintf(stdout,"src file length=%d\n",len);

ret = pthread_create(&tid1,NULL,copy_file,&args1);
if(ret != 0){
fprintf(stderr,"create pthread tid1 fail: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}

ret = pthread_create(&tid2,NULL,copy_file,&args2);
if(ret != 0){
fprintf(stderr,"create pthread tid2 fail: %s\n",strerror(errno));
exit(EXIT_FAILURE);
}

pthread_join(tid1,NULL);
pthread_join(tid2,NULL);

}


4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: