多进程和多线程文件拷贝

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);

}
  
时间: 2024-10-14 12:59:46

多进程和多线程文件拷贝的相关文章

JAVA程序设计(17)----- 制作文件拷贝软件 进程 输入流输出流 NIO 进度条 底层拷贝 多线程

使用NIO对文件进行底层拷贝(按照字节)多线程技术初级应用 不阻塞程序运行 package com.lovo.homework01; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import

linux下多进程的文件拷贝与进程相关的一些基础知识

之前实现了用文件IO的方式可以实现文件的拷贝,那么对于进程而言,我们是否也可以实现呢? 答案是肯定的. 进程资源: 首先我们先回顾一下,进程的运行需要哪些资源呢?其资源包括CPU资源,内存资源,当然还有时间片资源,我们都知道进程是有 栈, 堆,  只读数据段,  数据段(已初始化的全局变量静态变量),bss段(未初始化的),   代码段还有一组寄存器值. 进程命令: 另外我们也可以通过 ps  -ef |grep 进程名命令来查看进程号(PID)和父进程号(PPID),之后还可以通过 ps au

0730------Linux网络编程----------服务器端模型(迭代,多进程,多线程,select,poll,epoll 等)

1.迭代服务器模型 1.1 迭代服务器是处理多个请求时一种最简单直接的思路,即使用while循环,它不具有并发能力,即必须一个一个的处理客户的请求. 1.2 程序示例. #include "def.h" int listenfd_init(); //返回一个处于监听状态的套接字描述符 void do_service(int peerfd); // 处理客户端的请求 int main(int argc, const char *argv[]) { if(signal(SIGPIPE, S

Python3 多进程和多线程

Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回. 子进程永远返回0,而父进程返回子进程的ID.这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getpid()就可以拿到父进程的ID. Python的os模块封装了常见的系统调用,其中就包括fork

学习整理——多进程和多线程概念理解

进程 一个进程,包括了代码.数据和分配给进程的资源(内存),在计算机系统里直观地说一个进程就是一个PID.操作系统保护进程空间不受外部进程干扰,即一个进程不能访问到另一个进程的内存.有时候进程间需要进行通信,这时可以使用操作系统提供进程间通信机制.通常情况下,执行一个可执行文件操作系统会为其创建一个进程以供它运行.但如果该执行文件是基于多进程设计的话,操作系统会在最初的进程上创建出多个进程出来,这些进程间执行的代码是一样,但执行结果可能是一样的,也可能是不一样的. 为什么需要多进程?最直观的想法

进程实现文件拷贝

## 一.复制文件到当前目录下import os, sysfrom multiprocessing import Poolfrom multiprocessing import Manager def copy_file(name, path, new_path, q): fr = open(path + "/" + name) fw = open(new_path + '/' + name, "w") content = fr.read() fw.write(co

多进程与多线程差别

 在Unix上编程採用多线程还是多进程的争执由来已久,这样的争执最常见到在C/S通讯中服务端并发技术 的选型上,比方WEBserver技术中.Apache是採用多进程的(perfork模式,每客户连接相应一个进程,每进程中仅仅存在唯一一个运行线程), Java的Web容器Tomcat.Websphere等都是多线程的(每客户连接相应一个线程,全部线程都在一个进程中). 从Unix发展历史看,伴随着Unix的诞生进程就出现了.而线程非常晚才被系统支持,比如Linux直到内核2.6.才支持符合P

多进程 vs 多线程

今天和一个朋友聊天,谈到了多进程.多线程的区别,回来搜集文章给出结论: 在Linux2.6上,多线程并不比多进程速度快,考虑到线程栈的问题,多进程在并发上有优势. 转载一篇 在Unix上编程采用多线程还是多进程的争执由来已久,这种争执最常见到在C/S通讯中服务端并发技术 的选型上,比如WEB服务器技术中,Apache是采用多进程的(perfork模式,每客户连接对应一个进程,每进程中只存在唯一一个执行线程), Java的Web容器Tomcat.Websphere等都是多线程的(每客户连接对应一个

【Linux】多进程与多线程之间的区别

http://blog.csdn.net/byrsongqq/article/details/6339240 网络编程中设计并发服务器,使用多进程与多线程 ,请问有什么区别?  答案一: 1,进程:子进程是父进程的复制品.子进程获得父进程数据空间.堆和栈的复制品. 2,线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列. 两者都可以提高程序的并发度,提高程序运行效率和响应时间. 线程和进程在使用上各有优缺点:线程执行开