zoukankan      html  css  js  c++  java
  • 复制文件[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

        

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

  • 相关阅读:
    LockFile文件-解决并发写入日志的问题
    二、Consul Service Mesh
    查看CPU和内存,用机器指令和汇编指令编程
    环境配置过程中的一些小tips
    工具使用指北:GDB
    瞧瞧我发现了什么
    新的目标:Capture The Flag
    python 实现的idw插值方法
    Python 利用 百度接口输入地点名字返回经纬度
    轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3065706.html
Copyright © 2011-2022 走看看