实习随手记-MFC多线程分解复制文件
来源:互联网 发布:大数据彩票预测王律强 编辑:程序博客网 时间:2024/05/22 12:19
//==================================在MFC 对应的 Dlg.cpp 中编写,前面都是固定生成的东西============// MFCApplication1Dlg.cpp : 实现文件//#include "stdafx.h"#include "MFCApplication1.h"#include "MFCApplication1Dlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx{public:CAboutDlg();// 对话框数据#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_ABOUTBOX };#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现protected:DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()// CMFCApplication1Dlg 对话框CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent /*=NULL*/): CDialogEx(IDD_MFCAPPLICATION1_DIALOG, pParent){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_PROGRESS1, m_progress);}BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDOK, &CMFCApplication1Dlg::OnBnClickedOk)ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication1Dlg::OnBnClickedButton1)ON_BN_CLICKED(IDC_OPEN_BUTTON, &CMFCApplication1Dlg::OnBnClickedOpenButton)ON_BN_CLICKED(IDCANCEL, &CMFCApplication1Dlg::OnBnClickedCancel)END_MESSAGE_MAP()// CMFCApplication1Dlg 消息处理程序BOOL CMFCApplication1Dlg::OnInitDialog(){CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动// 执行此操作SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标// TODO: 在此添加额外的初始化代码m_progress.SetRange(0, 100);m_progress.SetPos(0);return TRUE; // 除非将焦点设置到控件,否则返回 TRUE}void CMFCApplication1Dlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}}// 如果向对话框添加最小化按钮,则需要下面的代码// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,// 这将由框架自动完成。void CMFCApplication1Dlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CMFCApplication1Dlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}//=========================================多线程相关代码操作(开始)=======================================//DWORD dwThreadID[10]; // 线程ID//HANDLE hThread[10]; // 线程句柄HANDLE g_hThreadEvent;CRITICAL_SECTION g_csThreadCode; int THREAD_NUM ; //子线程个数FILE *fp, *fout;long size, one_size,last_size;// //你可以 更改大小volatile long g_nNum; //全局资源//HANDLE g_hThreadParameter;struct THREAD_INFO {int sumnum;int num;};THREAD_INFO Info;DWORD WINAPI Fun(LPVOID lpParam){//由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来 THREAD_INFO* pInfo = (THREAD_INFO*)lpParam; //线程获取传来的结构体参数Sleep(50);SetEvent(g_hThreadEvent); //触发事件EnterCriticalSection(&g_csThreadCode);//进入各子线程互斥区域 //------------------------进行复制工作(需要将文件进行分块)---------------------- // 全局变量Sleep(0);fseek(fp, pInfo->num*one_size, SEEK_SET);//移动到要复制的位置fseek(fout, pInfo->num*one_size, SEEK_SET);//移动到要复制的位置//若1个子线程if (pInfo->sumnum == 1){char* buff; //开缓存buff = (char*)malloc(sizeof(char)*one_size);memset(buff, 0, sizeof(char)*one_size);//读fread(buff, 1, one_size, fp);//写fwrite(buff, 1, one_size, fout);//关缓存free(buff);buff = NULL;//回文件指针rewind(fp);rewind(fout);}//若多个子线程else {if (pInfo->num < pInfo->sumnum - 1){char* buff; //开缓存buff = (char*)malloc(sizeof(char)*one_size);memset(buff, 0, sizeof(char)*one_size);//读fread(buff, 1, one_size, fp);//写fwrite(buff, 1, one_size, fout);//关缓存free(buff);buff = NULL;//回文件指针rewind(fp);rewind(fout);}else {char* buff; //开缓存buff = (char*)malloc(sizeof(char)*last_size);memset(buff, 0, sizeof(char)*last_size);//读fread(buff, 1, last_size, fp);//写fwrite(buff, 1, last_size, fout);//关缓存free(buff);buff = NULL;//回文件指针rewind(fp);rewind(fout);}}//int pos = g_nNum;//m_progress.SetPos(pos*100/THREAD_NUM); //设置进度条的位置g_nNum++; //------------------------------------------------------------------------------LeaveCriticalSection(&g_csThreadCode);//离开互斥区return 0;}//“拷贝”按钮的响应void CMFCApplication1Dlg::OnBnClickedOk(){// TODO: 在此添加控件通知处理程序代码//接收编辑框输入设置里的“线程数”和“路径”g_nNum = 0;CString str;UpdateData();THREAD_NUM = GetDlgItemInt(IDC_THREADNUM_EDIT, NULL, 1); //若看做有符号数,则bSigned为1,返回值直接以int类型去接收GetDlgItem(IDC_OPEN_EDIT)->GetWindowText(str);LPCTSTR src = str.GetString();//路径转换成窄字符DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, src, -1, NULL, 0, NULL, FALSE);//计算这个UTF8实际有几个字节组成char* psText = new char[dwNum];if (!psText){delete[]psText;}WideCharToMultiByte(CP_OEMCP, NULL, src, -1, psText, dwNum, NULL, FALSE);fp = fopen(psText, "rb");//源文件if (fp == NULL) { AfxMessageBox(_T("源文件读取失败")); return ; }fseek(fp, 0, SEEK_END); // non-portablesize = ftell(fp);//得到源文件大小rewind(fp);//若1个子线程if (THREAD_NUM ==1 ){one_size = size ;//得到整块的大小last_size = 0;//分完块不够一整块的最后小块的大小}//若多个子线程else if (THREAD_NUM > 1){one_size = size/ (THREAD_NUM-1);//得到整块的大小last_size = size% (THREAD_NUM - 1);//分完块不够一整块的最后小块的大小}fout = fopen("copy.txt", "wb+");//目标文件还有为她开出与源文件同大小的空间char* buffdet; //开缓存buffdet = (char*)malloc(sizeof(char)*size);memset(buffdet, 0, sizeof(char)*size);fwrite(buffdet, 1, size, fout);free(buffdet);buffdet = NULL;rewind(fout);g_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);InitializeCriticalSection(&g_csThreadCode);HANDLE hThread[20]; // 线程句柄CString strtime;long t1 = GetTickCount();//程序段开始前取得系统运行时间(ms)for (int i = 0; i < THREAD_NUM; i++){ //把第i个线程要处理的文件块内容传递过去Info.num = g_nNum;Info.sumnum = THREAD_NUM;hThread[i] = CreateThread(NULL, 0, Fun, &Info, 0, NULL);//等子线程接收到参数时主线程可能改变了这个i的值WaitForSingleObject(g_hThreadEvent, INFINITE); //等待事件被触发}// //保证子线程已全部运行结束WaitForMultipleObjects(THREAD_NUM, hThread, TRUE, INFINITE); CloseHandle(g_hThreadEvent);DeleteCriticalSection(&g_csThreadCode);fclose(fp);fclose(fout);long t2 = GetTickCount();//程序段结束后取得系统运行时间(ms) strtime.Format(_T("拷贝时间: %ld ms"), t2 - t1);//前后之差即程序运行时间 delete[]psText;AfxMessageBox(strtime);}void CMFCApplication1Dlg::OnBnClickedButton1(){// TODO: 在此添加控件通知处理程序代码//TerminateThread(hThread,-1);//WaitForSingleObject(hThread, INFINITE);//等待单个线程(线程耗时很长)彻底推出}//"打开文件"按钮响应void CMFCApplication1Dlg::OnBnClickedOpenButton(){// TODO: 在此添加控件通知处理程序代码// 设置过滤器 TCHAR szFilter[] = _T("文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||");// 构造打开文件对话框 CFileDialog fileDlg(TRUE, _T("txt"), NULL, 0, szFilter, this);CString strFilePath;// 显示打开文件对话框 if (IDOK == fileDlg.DoModal()){// 如果点击了文件对话框上的“打开”按钮,则将选择的文件路径显示到编辑框里 strFilePath = fileDlg.GetPathName();SetDlgItemText(IDC_OPEN_EDIT, strFilePath);}}void CMFCApplication1Dlg::OnBnClickedCancel(){// TODO: 在此添加控件通知处理程序代码CDialogEx::OnCancel();}
阅读全文
0 0
- 实习随手记-MFC多线程分解复制文件
- 实习随手记-文件系列操作
- 实习随手记-
- 实习随手记-注册表
- 实习随手记-文件操作(windows函数)
- MFC随手记之一
- C# 多线程随手记
- MFC随手记之四_文件查找器
- 实习随手记-win32创建窗口操作
- 实习随手记-win32进程操作
- 实习随手记--破产版小病毒
- mfc编码风格随手记
- MFC 文件复制
- MFC 复制文件
- MFC 文件复制
- MFC文件复制、删除
- MFC文件复制、删除
- MFC文件复制、删除
- Socket通信时报错java.net.ConnectException: Connection refused
- 去掉数组中重复的数字
- 13.创建活动、布局、活动关联布局、注册活动
- FZU1205 之 小鼠迷宫问题
- webpack 学习经验1
- 实习随手记-MFC多线程分解复制文件
- javaWeb服务详解(含源代码,测试通过,注释) ——applicationContext-dao.xml
- python3 查看解释器和包安装路径
- MySQL5.7改密码
- windows下配置hadoop开发环境
- python基础之三——函数
- Cocos2d-X游戏开发(五)
- LibXL库使用详解(篇一)
- 线程创建和启动:继承Thread类和实现Runnable接口