A!die Software Studio Welcome to A!Die Software Studio

切换线程执行路径的一个问题

by adie
2013-08-02 16:10:19
  1. #include <stdio.h>  
  2. #define _WIN32_WINNT 0x0501  
  3. #include <windows.h>  
  4.   
  5. volatile long th1_start = 0;  
  6. volatile long th1_continue = 0;  
  7. volatile long th2_finished = 0;  
  8.   
  9. DWORD WINAPI thread_fun1(LPVOID arg)  
  10. {  
  11.     //printf("fun 1: Enter!\n");                                        // mark1  
  12.     InterlockedIncrement(&th1_start);  
  13.   
  14.     while(!th1_continue)  
  15.     {  
  16.         Sleep(1);  
  17.     }  
  18.   
  19.     printf("fun 1: Hello!\n");  
  20.     printf("fun 1: World!\n");  
  21.   
  22.     return 0;  
  23. }  
  24.   
  25. void fun2()  
  26. {  
  27.     printf("fun 2: Hello!\n");  
  28.     printf("fun 2: China!\n");  
  29.   
  30.     InterlockedIncrement(&th2_finished);  
  31.   
  32.     while(1)    // 阻止线程退出  
  33.     {  
  34.         Sleep(50);  
  35.     }  
  36. }  
  37.   
  38. long WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS* ep)  
  39. {  
  40.     printf("Exception...\n");  
  41.     return EXCEPTION_EXECUTE_HANDLER;  
  42. }  
  43.   
  44. int main()  
  45. {  
  46.     //AddVectoredExceptionHandler(1, ExceptionFilter);  
  47.     //SetUnhandledExceptionFilter(ExceptionFilter);  
  48.   
  49.     //printf("Begin Create Thread...\n");                       // mark2  
  50.     HANDLE hThread = CreateThread(NULL, 0, thread_fun1, 0, 0, 0);  
  51.       
  52.     while(!th1_start)  
  53.         Sleep(1);  
  54.   
  55.     BYTE* tempStack = new BYTE[1024 * 1024];  
  56.   
  57.       
  58.     SuspendThread(hThread);  
  59.     CONTEXT ctx;  
  60.     ctx.ContextFlags = CONTEXT_FULL;  
  61.     GetThreadContext(hThread, &ctx);  
  62.   
  63.     DWORD saveOldESP = ctx.Esp;  
  64.     DWORD saveOldEIP = ctx.Eip;  
  65.   
  66.     ctx.Esp = (DWORD)(DWORD_PTR)tempStack + 1024 * 1024;  
  67.     ctx.Eip = (DWORD)(DWORD_PTR)fun2;  
  68.     SetThreadContext(hThread, &ctx);  
  69.     ResumeThread(hThread);  
  70.   
  71.     while(!th2_finished)  
  72.     {  
  73.         Sleep(1);  
  74.     }  
  75.   
  76.     InterlockedIncrement(&th1_continue);  
  77.   
  78.     SuspendThread(hThread);  
  79.     ctx.Esp = saveOldESP;  
  80.     ctx.Eip = saveOldEIP;  
  81.     SetThreadContext(hThread, &ctx);  
  82.     ResumeThread(hThread);  
  83.   
  84.     delete [] tempStack;  
  85.     WaitForSingleObject(hThread, INFINITE);  
  86.     system("pause");  
  87.     return 0;  
  88. }

 

上面这份代码想强制把一个指定线程切换来调用一个指定函数, 调用完了后让线程继续回到原来的地方运行.

在 VC2005 下,  Release 版可以正常工作,  输出

fun 2: Hello!

fun 2: China!

fun 1: Hello!

fun 1: World!

Debug 版按 F5 运行也正常, 但是 Ctrl + F5 的话就直接退掉了, 捕获不到发生了什么异常. 如果把 mark1, makr2 任意一个注释打开, Debug 版 Ctrl + F5 运行就正常了. 

这到底是什么原因造成的啊? 是切换线程上下文的时候线程在内核态运行造成的么....

▲评论

› 网友 adie2 () 于 2013-08-05 12:39:28 发表评论说:

改成 blog.adintr.com/309 后上面的问题解决

X 正在回复:
姓 名: 留下更多信息
性 别:
邮 件:
主 页:
Q Q:
来 自:
职 业:
评 论:
验 证:


Valid HTML 4.01 Strict Valid CSS!
Copyleft.A!die Software Studio.ADSS
Power by webmaster@adintr.com