复制文件[POSIX线程模型系列3]_[使用线程池并发复制文件]

文章结束给大家来个程序员笑话:[M]

    

    场景:

    1.在复制多个文件时程线池也有用武之地,多程线复制文件是受io影响的,在设置必定的缓存时有必定效果。

    2.或者在Linux下有必定效果,但是在windows上用使fopen效果不太显明。有晓得的手高请指教。

    3.考参qt发并复制文件,并相沿之前的程线池实现。

    4.商用的话议建可以用boost的 http://sourceforge.net/projects/threadpool/?source=directory,如果是想用c的程线池实现,可以修改我写的。

    

    Qt的用调实现:

QList<QString> keys = m_Files.keys();  
    int num_files = keys.count();  
    QFutureSynchronizer<tuple<QString, QString> > sync;  
  
    for (int i = 0; i < num_files; ++i) {  
        QString id = keys.at(i);  
        sync.addFuture(QtConcurrent::run(  
                           this,  
                           &ImportEPUB::LoadOneFile,  
                           m_Files.value(id),  
                           m_FileMimetypes.value(id)));  
    }  
  
    sync.waitForFinished();

    我自己的实现从效果上其实复制速度还是有下落的。就和在windows上同时复制多个大文件不如先复制一个文件快。

    main.cpp

    每日一道理
那蝴蝶花依然花开花落,而我心中的蝴蝶早已化作雄鹰飞向了广阔的蓝天。
/*
 * main.cpp
 *
 *  Created on: 2013-3-13
 *  Author: Sai
 */

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <io.h>
using namespace std;

#include "dh_thread_pool.h"
#include "dh_thread_task.h"

#include "dh_download_manager.h"

typedef struct DiskData
{
	FILE* file;
} DiskData;

size_t WriteToDisk(void *contents, size_t size, size_t nmemb, void *userp)
{
	DiskData* dd = (DiskData*) userp;
	size_t number = nmemb * size;
	size_t writed_num = fwrite(contents, 1, number, dd->file);
	return writed_num;
}

void *RunTaskFunc(void * arg)
{
	int* i = (int*) arg;
	cout << "thread index: " << *i << endl;
	DhDownloadManager* manager = new DhDownloadManager();
	static const char* url =
			"http://www.istonsoft.com/downloads/iston-video-converter.exe";

	DiskData dd;
	char path[8];
	memset(path, 0, sizeof(path));
	sprintf(path, "%d.exe", *i);
	dd.file = fopen(path, "wb");
	manager->Process(url, &WriteToDisk, &dd);

	fclose(dd.file);
	return NULL;
}

void Download()
{
	printf("Hello, world\n");
	DhThreadPool *pool = new DhThreadPool(5);
	pool->Activate();

	for (int o = 0; o < 10; ++o)
	{
		int *i = new int;
		*i = o;
		pool->AddAsynTask(&RunTaskFunc, i);
	}
	getchar();
	pool->Destroy();
	delete pool;
}

void CopyOneToAnother(const char* source, const char* dest)
{
	FILE* file_r = fopen(source, "rb");
	FILE* file_w = fopen(dest, "wb");

	char buf[1025];
	buf[1024] = 0;
	while (!feof(file_r))
	{
		memset(buf, 0, 1024);
		int readed = fread(buf, 1, 1024, file_r);
		fwrite(buf, 1, readed, file_w);
	}
	fclose(file_r);
	fclose(file_w);
}

void CopyFileWithOneThread()
{
	double time = clock();
	static string dir("dist/");
	static string d_dir("dist/Debug/");
	for (int i = 1; i < 11; ++i)
	{
		char file_name[8];
		memset(file_name, 0, sizeof(file_name));
		sprintf(file_name, "%d.bin", i);
		string path(dir);
		path.append(file_name);
		string d_path(d_dir);
		d_path.append(file_name);
		CopyOneToAnother(path.c_str(), d_path.c_str());
	}

	cout << "单程线复制文件 耗时 单位(毫秒): " << clock() - time << endl;
}

void *CopyFile(void * arg)
{
	int* data = (int*) arg;
	static string dir("dist/");
	static string d_dir("dist/Debug/");

	char file_name[8];
	memset(file_name, 0, sizeof(file_name));
	sprintf(file_name, "%d.bin", *data);
	string path(dir);
	path.append(file_name);
	string d_path(d_dir);
	d_path.append(file_name);
	CopyOneToAnother(path.c_str(), d_path.c_str());

	free(data);
	return NULL;
}

void CopyFileWithConcurrentThread()
{
	double time = clock();

	DhThreadPool *pool = new DhThreadPool(5);
	pool->SetWaitTime(10);//设置扫描时间是10毫秒
	for (int o = 1; o < 11; ++o)
	{
		int *i = (int*) malloc(sizeof(int));
		*i = o;
		pool->AddAsynTask(&CopyFile, i);
	}
	pool->Activate();
	pool->WaitTaskFinishAndDestroy();
	delete pool;

	cout << "发并复制文件 耗时 单位(毫秒): " << clock() - time << endl;
}

int IsFileExist(const char* path)
{
	return !access(path, F_OK);
}

int CreateFixSizeFile(const char* file_path, uint64_t file_size)
{
	FILE* file = fopen(file_path, "wb");
	char buffer[1025];
	memset(buffer, 1, sizeof(buffer));
	uint64_t size = file_size;

	size_t num = 0;
	while (size)
	{
		num = fwrite(buffer, 1, 1024, file);
		size = size - num;
	}

	fclose(file);
	return 0;
}

int main(int argc, char *argv[])
{
	setbuf(stdout, (char*) NULL);
	setbuf(stderr, (char*) NULL);

	//1.创立文件
	string dir("dist/");
	for (int i = 1; i < 11; ++i)
	{
		char file_name[8];
		memset(file_name, 0, sizeof(file_name));
		sprintf(file_name, "%d.bin", i);
		string path(dir);
		path.append(file_name);
		if (!IsFileExist(path.c_str()))
		{
			CreateFixSizeFile(path.c_str(), 1024 * 1024 * 10 * i);
		}
	}
        
        //耗时
	//41500
	//42489
	//41368
	//1.单个程线复制文件
//	CopyFileWithOneThread();
        
        //耗时
	//85396
	//1.发并复制文件
	CopyFileWithConcurrentThread();

	return 0;
}

    考参程线池:

    http://blog.csdn.net/infoworld/article/details/8670951

    

文章结束给大家分享下程序员的一些笑话语录: 刹车失灵
有一个物理学家,工程师和一个程序员驾驶着一辆汽车行驶在阿尔卑斯山脉 上,在下山的时候,忽然,汽车的刹车失灵了,汽车无法控制地向下冲去, 眼看前面就是一个悬崖峭壁,但是很幸运的是在这个悬崖的前面有一些小树 让他们的汽车停了下来, 而没有掉下山去。 三个惊魂未定地从车里爬了出来。
物理学家说, “我觉得我们应该建立一个模型来模拟在下山过程中刹车片在高 温情况下失灵的情形”。
工程师说, “我在车的后备厢来有个扳手, 要不我们把车拆开看看到底是什么 原因”。
程序员说,“为什么我们不找个相同的车再来一次以重现这个问题呢?”

你可能感兴趣的:(线程池)