目标:将一单线程Console程序改为MFC多线程。而且线程间无需通讯。
现状:
1、Windows线程栈,每线程都有自己的独立栈。
进程创立时会创建一主线程。
每线程栈存储默认1MB。
2、Windows为抢先式多任务操作系统。
级别高的线程会先运行。
3、malloc序列化存储申请请求。
Applications can safely use the memory management features of the C run-time
library ( malloc, free, and so on) and C++ ( new, delete, and so on).
4、MFC书看过一些,但没操作过。代码写过一些,都是结构化函数调用。
最初想法:十来行,半小时搞定。
实际过程:
1、Console迁移到MFC比较简单。问题是我用的visual studio 2012对话框都继承自CDialogEx,这样生成的窗口
居然怎么操作都不会失去焦点,要想跟踪的话感觉是白花功夫,一番搜索,对话框改为继承自CDialog,搞定。
2、调用线程API,实现多线程。
生成的结果完全不符预期,甚至怀疑自己关于windows的知识是否正确。
这个阶段忽略了调试器的信息,那就是9号线程居然特别多,按设计应该只有一个,这么一个机会被忽略了。
晚上的时候开始使用Windbg进行跟踪,才意识到线程和函数调用差别还挺大,函数调用参数都直接传过去,调用者栈
上保留参数的副本,这个线程创建就不一样,用的参数要自行提供。明白了这一点就豁然开朗了。
3、示例代码。
Debug模式运行了一下,速度在3632QM上比Console程序Release模式下快多了。20MB的测试文件CPU占用率直接冲上100%。
1 for (i=0; i<TABLE_QUANTTITY; ++i){
2 quickCdnEntropySubtractPolicy(&SubTables[i], sigMatrix[i], attPresent, &dcnEquClsCard[i][0]);
3 }
1 for (i=0; i<TABLE_QUANTTITY; ++i){
2 ...
3
4 ...
5 thread[i] = ::CreateThread(NULL, 0, ThreadSubtractPolicy, (PVOID) &rt[i], CREATE_SUSPENDED, NULL);
6 assert(thread[i] != NULL);
7 }
8 for (i=0; i<TABLE_QUANTTITY; i++) ::ResumeThread(thread[i]);
9 ::WaitForMultipleObjects(TABLE_QUANTTITY, thread, true, INFINITE);
10 for (i=0; i<TABLE_QUANTTITY; ++i){
11 ::GetExitCodeThread(thread[i], &exitCode[i]);
12 ::CloseHandle(thread[i]);
13 thread[i] = NULL;
14 }
15
16 DWORD WINAPI ThreadSubtractPolicy(_In_ LPVOID lpParameter){
17 reductTbl * rt = (reductTbl *)lpParameter;
18 quickCdnEntropySubtractPolicy(rt->dt, rt->sig, rt->attPresent, rt->dcnEquClsCard);
19
20 return 0;
21 }