- //文件类型
- enum E_FILETYPE
- {
- E_C,
- E_JAVA
- };
- //文件行数信息
- struct T_CodeFileMsg
- {
- int nTaskId; //任务Id
- string FileName; //文件名称
- E_FILETYPE eFiletype; //文件类型
- int nTotalLine; //总行数
- int nEmptyLine; //空行数
- int nCodeLine; //代码行数
- int nNoteLine; //注释行数
- T_CodeFileMsg()
- {
- nTotalLine = 0;
- nEmptyLine = 0;
- nCodeLine = 0;
- nNoteLine = 0;
- }
- };
- #define MAX_WORKTHREAD 5 //线程最大数
- #define MAX_LEN 1024 //路径最大长度
- #define MAX_CHAR 1024 //一行最大字符数
- //线程函数
- DWORD WINAPI ReadFileThread(LPVOID lpParam);
- DWORD WINAPI WorkThread(LPVOID lpParam);
- //线程句柄
- DWORD g_dwReadFileThreadID;
- DWORD g_dwTaskThread;
- DWORD g_dwWorkThread[MAX_WORKTHREAD];
- //事件句柄
- HANDLE g_EventReadFileHandle;
- HANDLE g_EventReadFinishHandle;
- //临界区
- CRITICAL_SECTION g_cs;
- CRITICAL_SECTION g_MsgQueue;
- CRITICAL_SECTION g_task;
- CRITICAL_SECTION g_MsgMap;
- //数据
- map<int, int>m_task;
- std::deque<int> m_MsgQueue;
- std::deque<int> m_FileQueue;//任务队列
- std::map<int, T_CodeFileMsg*> m_FileMsgMap;//处理文件与文件行数信息
- int WorkThreadCout = 0;
- int nTotalTaskCount =0;
- int nWorkTaslCount=0;
- int nTaskBeginTime;
- int nReadFileFinish=0;
- int nInitCount= 0;
- int nWorkFlag = 0;
- bool bRunFlag = TRUE;
- char g_workPath[MAX_LEN];
- bool bReadFileFlag=TRUE;
- int g_nTaskId=0;
- int main()
- {
- int i;
- cout << "#####代码行数统计测试开始#####" <<endl;
- cout << "Main thread is running." << endl;
- //初始化临界区
- InitializeCriticalSection(&g_cs);
- InitializeCriticalSection(&g_MsgQueue);
- InitializeCriticalSection(&g_MsgMap);
- g_EventReadFileHandle = ::CreateEvent(NULL,TRUE,TRUE,NULL);
- g_EventReadFinishHandle = ::CreateEvent(NULL,TRUE,TRUE,NULL);
- //创建线程
- HANDLE hRFTHandle = CreateThread(NULL, 0, ReadFileThread, NULL, 0, &g_dwReadFileThreadID);
- HANDLE hWTHandle[MAX_WORKTHREAD];
- for (i=0; i<MAX_WORKTHREAD; i++)
- {
- int* nTemp = new int;//如果不new,最后打印出来的WorkThread(LPVOID lpParam)的都是10
- //nTemp = &i;和*nTemp = i;区别。
- *nTemp = i;
- hWTHandle[i] = CreateThread(NULL, 0, WorkThread, nTemp, 0, &g_dwWorkThread[i]);
- WorkThreadCout ++;
- m_task[i] = 0;
- Sleep(100);
- }
- while (TRUE)
- {
- if (nWorkFlag == 0)
- {
- printf("输入要统计文件的路径或end退出\n");
- scanf("%s", g_workPath);
- DeleteMap();
- g_nTaskId = 0;
- nWorkTaslCount = 0;
- if (strcmp(g_workPath, "end") == 0)
- {
- bReadFileFlag = FALSE;//读文件线程标志
- SetEvent(g_EventReadFileHandle);//读事件
- bRunFlag = FALSE;//让线程退出
- break;
- }
- SetEvent(g_EventReadFileHandle);//读事件
- nWorkFlag = 1;
- }
- ResetEvent(g_EventReadFinishHandle);
- WaitForSingleObject(g_EventReadFinishHandle, INFINITE);
- if (nReadFileFinish == 1)
- {
- PrintMsg();
- }
- }
- Sleep(3000);
- DeleteMap();
- CloseHandle(hRFTHandle);
- for (i=0; i<MAX_WORKTHREAD; i++)
- {
- CloseHandle(hWTHandle[i]);
- }
- CloseHandle(g_EventReadFileHandle);
- CloseHandle(g_EventReadFinishHandle);
- DeleteCriticalSection(&g_cs);
- DeleteCriticalSection(&g_MsgQueue);
- DeleteCriticalSection(&g_MsgMap);
- cout << "Main thread is end." << endl;
- cout << "#####代码行数统计测试结束#####" <<endl;
- //system("pause");
- return 0;
- }
- int InitData()
- {
- return 0;
- }
- int DeleteMap()
- {
- std::map<int, T_CodeFileMsg*>::iterator IterFile;
- for(IterFile=m_FileMsgMap.begin(); IterFile!=m_FileMsgMap.end(); IterFile++)
- {
- T_CodeFileMsg* file = (*IterFile).second;
- delete file;
- file = NULL;
- }
- m_FileMsgMap.clear();
- return 0;
- }
- DWORD WINAPI ReadFileThread(LPVOID lpParam)
- {
- // cout << "No." << g_dwThreadID << " thread is running." << endl;
- while (bRunFlag)
- {
- EnterCriticalSection(&g_cs);
- cout << "ReadFileThread " << g_dwReadFileThreadID << " thread is running." << endl;
- LeaveCriticalSection(&g_cs);
- ResetEvent(g_EventReadFileHandle);
- WaitForSingleObject(g_EventReadFileHandle, INFINITE);
- if (bReadFileFlag)
- {
- int nTemp = DirectoryList(g_workPath);//nReadFileFinish
- nReadFileFinish = nTemp;
- if (nTemp == 1)
- {
- PrintFile();
- nWorkFlag = 0;
- nTotalTaskCount = g_nTaskId;
- }
- else
- {
- nWorkFlag = 0;
- }
- SetEvent(g_EventReadFinishHandle);
- }
- Sleep(1000);
- }
- cout << "ReadFileThread " << g_dwReadFileThreadID << " end" << endl;
- return 0;
- }
- DWORD WINAPI WorkThread(LPVOID lpParam)
- {
- // cout << "No." << g_dwThreadID << " thread is running." << endl;
- int* nRemp = (int*)lpParam;
- while (bRunFlag)
- {
- int n = -1;
- T_CodeFileMsg* pCFMsg=NULL;
- EnterCriticalSection(&g_cs);
- //cout << "No " << *nRemp << ", " << g_dwWorkThread[*nRemp] << " thread is running." << endl;
- LeaveCriticalSection(&g_cs);
- EnterCriticalSection(&g_MsgQueue);
- if (!m_FileQueue.empty())
- {
- n = m_FileQueue.front();
- m_FileQueue.pop_front();
- if (nWorkTaslCount == 0)
- {
- nTaskBeginTime = GetTickCount();
- }
- nWorkTaslCount++;
- m_task[*nRemp]++;
- }
- LeaveCriticalSection(&g_MsgQueue);
- EnterCriticalSection(&g_MsgMap);
- if ( n>= 0)//没有这个,在开始的时候n=-1会造成溢出。
- pCFMsg = m_FileMsgMap[n];
- LeaveCriticalSection(&g_MsgMap);
- EnterCriticalSection(&g_cs);
- //cout << "No:" << *nRemp << ", " << n << endl;
- if (pCFMsg!=NULL)
- {
- cout << pCFMsg->FileName.c_str() << endl;
- }
- LeaveCriticalSection(&g_cs);
- if (pCFMsg!=NULL && n>=0)
- {
- ProcessFile(pCFMsg, n);
- Sleep(20);
- }
- else
- Sleep(2000);
- }
- delete nRemp;
- nRemp = NULL;
- cout << "No " << lpParam << " end" << endl;
- return 0;
- }
- //根据文件类型处理
- int ProcessFile(T_CodeFileMsg* pTCFMsg, int n)
- {
- EnterCriticalSection(&g_MsgMap);
- string tempFile = pTCFMsg->FileName;
- E_FILETYPE c_type = pTCFMsg->eFiletype;
- LeaveCriticalSection(&g_MsgMap);
- switch(c_type)
- {
- case E_C:
- ProcessCFile(pTCFMsg, tempFile.c_str(), n);
- break;
- case E_JAVA:
- ProcessJavaFile(pTCFMsg, tempFile.c_str(), n);
- break;
- default:
- break;
- }
- return 0;
- }
- int ProcessCFile(T_CodeFileMsg* pTCFMsg, char* strFile, int n)
- {
- ifstream in;
- char buf[MAX_CHAR] = {0};
- bool bNoteFlag = FALSE;
- int nNoteLine = 0;
- int nEmptyLine = 0;
- int nCodeLine = 0;
- int nTotalLine = 0;
- in.open(strFile);
- while(in.getline(buf, sizeof(buf)))
- {
- nTotalLine++;
- char* p = buf;
- while((*p ==' ' || *p=='\t')) p++;
- if (!bNoteFlag)
- {
- if (*p == 0)
- {
- nEmptyLine++;
- cout << nTotalLine <<endl;
- }
- else if (strncmp(p, "/*", 2)==0)
- {
- char* q = buf+strlen(buf)-1;
- while((*q ==' ' || *q=='\t')) q--;
- q--;
- //判断是不是/*AAA*/
- if (strncmp(q, "*/", 2)==0)
- {
- }
- else
- bNoteFlag = TRUE;
- nNoteLine++;
- cout << nTotalLine <<endl;
- }
- else if (strncmp(p, "//", 2)==0)
- {
- nNoteLine++;
- cout << nTotalLine <<endl;
- }
- else
- {
- nCodeLine++;
- }
- }
- else
- {
- if (*p == 0)
- {
- nNoteLine++;
- cout << nTotalLine <<endl;
- }
- else if (strncmp(p, "*/", 2)==0)
- {
- bNoteFlag = FALSE;
- nNoteLine++;
- cout << nTotalLine <<endl;
- }
- else
- {
- nNoteLine++;
- cout << nTotalLine <<endl;
- char* q = buf+strlen(buf)-1;
- while((*q ==' ' || *q=='\t')) q--;
- q--;
- if (strncmp(q, "*/", 2)==0)
- {
- bNoteFlag = FALSE;
- }
- }
- }
- memset(buf, 0, MAX_CHAR);
- }
- EnterCriticalSection(&g_MsgMap);
- pTCFMsg->nCodeLine = nCodeLine;
- pTCFMsg->nEmptyLine = nEmptyLine;
- pTCFMsg->nNoteLine = nNoteLine;
- pTCFMsg->nTotalLine = nTotalLine;
- m_FileMsgMap[n] = pTCFMsg;
- LeaveCriticalSection(&g_MsgMap);
- return 0;
- }
- int ProcessJavaFile(T_CodeFileMsg* pTCFMsg, char* strFile, int n)
- {
- return 0;
- }
- int AddFile2Map(char* pFile)
- {
- string strFile = strlwr(pFile);
- int nRet = strFile.find(".", 0);
- if (nRet>0)
- {
- string Temp;
- int nLen = strFile.size();
- Temp = strFile.substr(nRet, strFile.size()-nRet);
- if (strcmp(Temp.c_str(),".c")==0 || strcmp(Temp.c_str(),".cpp")==0 || strcmp(Temp.c_str(),".h")==0)
- {
- T_CodeFileMsg* pTemp = new T_CodeFileMsg;
- m_FileMsgMap[g_nTaskId] = pTemp;
- //m_FileMsgMap[g_nTaskId] = new T_CodeFileMsg;
- //T_CodeFileMsg* pTemp = m_FileMsgMap[g_nTaskId];
- pTemp->eFiletype = E_C;
- pTemp->nTaskId = g_nTaskId;
- pTemp->FileName = pFile;
- //pTemp->FileName = new char[nLen+1];
- //memcpy(pTemp->FileName, strFile.c_str(), nLen);
- //m_FileMsgMap[g_nTaskId] = pTemp;
- //m_FileMsgMap.insert(pair <int, T_CodeFileMsg* >(g_nTaskId, pTemp));
- m_FileQueue.push_back(g_nTaskId);
- g_nTaskId++;
- }
- }
- return 0;
- }
- int DirectoryList(LPCSTR Path)
- {
- WIN32_FIND_DATA FindData;
- HANDLE hError;
- int FileCount = 0;
- char FilePathName[MAX_LEN];
- // 构造路径
- char FullPathName[MAX_LEN];
- strcpy(FilePathName, Path);
- strcat(FilePathName, "\\*.*");
- hError = FindFirstFile(FilePathName, &FindData);
- if (hError == INVALID_HANDLE_VALUE)
- {
- printf("搜索失败!\n");
- return 0;
- }
- while(::FindNextFile(hError, &FindData))
- {
- // 过虑.和..
- if (strcmp(FindData.cFileName, ".") == 0
- || strcmp(FindData.cFileName, "..") == 0 )
- {
- continue;
- }
- // 构造完整路径
- wsprintf(FullPathName, "%s\\%s", Path,FindData.cFileName);
- FileCount++;
- AddFile2Map(FullPathName);
- // 输出本级的文件
- //printf("\n%d %s ", FileCount, FullPathName);
- if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- //printf("<Dir>");
- DirectoryList(FullPathName);
- }
- }
- return 1;
- }
- int PrintFile()
- {
- EnterCriticalSection(&g_MsgMap);
- std::map<int, T_CodeFileMsg*>::iterator IterFile;
- for(IterFile=m_FileMsgMap.begin(); IterFile!=m_FileMsgMap.end(); IterFile++)
- {
- T_CodeFileMsg* file = (*IterFile).second;
- //EnterCriticalSection(&g_cs);
- cout << endl;
- cout << file->FileName.c_str();
- cout << ", id:" << file->nTaskId;
- cout << ", nCodeLine:"<< file->nCodeLine;
- cout << ", nEmptyLine:"<< file->nEmptyLine;
- cout << ", nNoteLine:"<< file->nNoteLine;
- cout << ", nTotalLine:"<< file->nTotalLine;
- //LeaveCriticalSection(&g_cs);
- }
- LeaveCriticalSection(&g_MsgMap);
- return 0;
- }
- int PrintMsg()
- {
- while (TRUE)
- {
- if (nWorkTaslCount == nTotalTaskCount)
- {
- std::map<int, int>::iterator IterCount;
- for(IterCount=m_task.begin(); IterCount!=m_task.end();IterCount++)
- {
- int nThreadId= (*IterCount).first;
- int nCount = (*IterCount).second;
- EnterCriticalSection(&g_cs);
- cout << "nThreadId:" << nThreadId << ", nCount:" << nCount<<endl;
- LeaveCriticalSection(&g_cs);
- (*IterCount).second = 0;
- }
- nWorkFlag = 0;
- PrintFile();
- break;
- }
- cout << "nWorkTaslCount:" << nWorkTaslCount << ", nTotalTaskCount:" << nTotalTaskCount <<endl;
- Sleep(1000);
- }
- return 0;
- }