基于FormView的一个可视化程序,点击某按钮以后遍历文件夹,当找到一个文件时,就启动一个副线程并在这个线程中执行某些操作,代码如下:void CXXXView::DelDir(const CString &strDirName)
{ CString strTarget = strDirName + "\\*.*";
CFileFind finder;
BOOL bWorking = finder.FindFile((LPCTSTR)strTarget); while (bWorking)
{
bWorking = finder.FindNextFile();
if(finder.IsDots())
continue;
m_strFileName=finder.GetFilePath();
if(finder.IsDirectory())
{//递归调用
DelDir(m_strFileName);
}
else
{//启动线程
AfxBeginThread(FileDelThread,(void *)this);
}
}
}
m_strFileName是CXXXView的一个成员变量,通过线程传递的this指针就可以在线程里访问这个变量线程函数代码如下:UINT CXXXView::FileDelThread(void * param)
{
CXXXView * pView=(CXXXView *)param;
CString strFileName=pView->m_strFileName;
//对文件的操作用打印来代替,因为对文件操作要不断读写硬盘,所以启用线程,而不是在主线程的递归程序中完成
AfxMessageBox(strFileName);}
我建立一个文件夹A,A文件夹下面有文件1.txt和子文件夹B,子文件夹B下面有文件2.txt
执行程序却不能得到遍历的结果,两次打印的都是2.txt,这是什么原因,是不是两个子线程打印消息的时候m_strFileName已经更新为2.txt了呢?我也尝试传递文件名到线程中,这样是可以的,但是this指针就不能传递进来了,因为我要引用CXXXView里的一个CListBox对象用以显示遍历文件的情况,所以就有些矛盾了,可以传文件名,但是得不到this指针,传了this指针之后,又发现遍历文件有问题,怎么解决呢?
{ CString strTarget = strDirName + "\\*.*";
CFileFind finder;
BOOL bWorking = finder.FindFile((LPCTSTR)strTarget); while (bWorking)
{
bWorking = finder.FindNextFile();
if(finder.IsDots())
continue;
m_strFileName=finder.GetFilePath();
if(finder.IsDirectory())
{//递归调用
DelDir(m_strFileName);
}
else
{//启动线程
AfxBeginThread(FileDelThread,(void *)this);
}
}
}
m_strFileName是CXXXView的一个成员变量,通过线程传递的this指针就可以在线程里访问这个变量线程函数代码如下:UINT CXXXView::FileDelThread(void * param)
{
CXXXView * pView=(CXXXView *)param;
CString strFileName=pView->m_strFileName;
//对文件的操作用打印来代替,因为对文件操作要不断读写硬盘,所以启用线程,而不是在主线程的递归程序中完成
AfxMessageBox(strFileName);}
我建立一个文件夹A,A文件夹下面有文件1.txt和子文件夹B,子文件夹B下面有文件2.txt
执行程序却不能得到遍历的结果,两次打印的都是2.txt,这是什么原因,是不是两个子线程打印消息的时候m_strFileName已经更新为2.txt了呢?我也尝试传递文件名到线程中,这样是可以的,但是this指针就不能传递进来了,因为我要引用CXXXView里的一个CListBox对象用以显示遍历文件的情况,所以就有些矛盾了,可以传文件名,但是得不到this指针,传了this指针之后,又发现遍历文件有问题,怎么解决呢?
{
CFileFind finder;
BOOL bWorking = finder.FindFile(strDirName + _T("\\*.*")); while (bWorking)
{
bWorking = finder.FindNextFile(); if (finder.IsDots())
continue; if (finder.IsDirectory())
{
//递归调用
DelDir(finder.GetFilePath());
}
else
{
//启动线程
AfxBeginThread(FileDelThread, (LPCTSTR)finder.GetFilePath());
}
}
线程中?(MyInfo*)pInfo=(MyInfo*)param;
pInfo->来访问this 指针和文件名两个变量...
struct stParam
{
CListBox * box;
CString str;
};启动线程前这样改
stParam *pstParam=(stParam *)malloc(sizeof(struct stParam));
pstParam->box=&m_listbox;
pstParam->str=m_strFileName;
AfxBeginThread(FileDelThread,(void *)pstParam);线程中改为
stParam *ptheParam=(stParam *)param;
AfxMessageBox(ptheParam->str);
free(ptheParam);
还是有错,是哪里出了问题呢
多个线程同时工作的时候需要考虑并发与同步:建议你在主线程中定义成员变量:vector<string> colName;
并增加对应的互斥对象CRITICAL_SECTION m_csName;
用法:
主线程的构造函数中添加:InitializeCriticalSection(&m_csName);
析构函数中: DeleteCriticalSection (&m_csName);
每次遍历到一个文件:
EnterCriticalSection(&m_csName);
colName.push_bach(strFileName);
LeaveCriticalSection(&m_csName);
在工作线程中获取文件名:
string strFileName;
EnterCriticalSection(&m_csName);
strFileName = colName.front();
colName.erase(colName.begin());
LeaveCriticalSection(&m_csName);