转载请注明原文出处,http://www.cnblogs.com/flyingcloude/p/6992343.html
通过切换线程的Context内容,使用单线程模拟多线程运行。在程序中需要使用到的API主要有以下这些:
GetThreadContext(HANDLE hThread, Context lpContext);
说明:GetThreadContext,将hThread的上下文保存到lpContext中
SetThreadContext(HANDLE hThread, const Context *lpContext);
说明:SetThreadContext,将lpContext的内容保存到hThread的上下文中。
[cpp] view plain copy
- #include <windows.h>
- #include <stdio.h>
- #define SEND_THREAD_ID 1
- #define RECV_THREAD_ID 2
- const UINT uiTimerID = 10;
- HANDLE mainhandle;
- CONTEXT send_context;
- CONTEXT recv_context;
- HANDLE hd_send_thread;
- HANDLE hd_recv_thread;
- //如果hd_send_thread运行, thread_id = 1;
- //如果hd_recv_thread运行, thread_id = 2;
- int cur_thread_id = 0;
- void send_thread_func()
- {
- static int send_msg_count = 0;
- while(1)
- {
- printf("send_msg_count:............................ %d\n", send_msg_count++);
- Sleep(1000);
- }
- }
- void recv_thread_func()
- {
- static int recv_msg_count = 0;
- while(1)
- {
- printf("recv_msg_count: --------------------%d\n", recv_msg_count++);
- Sleep(1000);
- }
- }
- VOID CALLBACK TimerFun(HWND hwnd, UINT a, UINT b, DWORD c)
- {
- static int nCount = 0;
- printf("TimerFun nCount: %d\n", nCount++);
- if(nCount == 0)
- {
- send_context.ContextFlags = CONTEXT_FULL;
- recv_context.ContextFlags = CONTEXT_FULL;
- GetThreadContext(mainhandle, &send_context); //保存主线程上下文
- GetThreadContext(mainhandle, &recv_context); //保存主线程上下文
- return;
- }
- if(nCount % 2 == 1) //启动hd_send_thread
- {
- if(cur_thread_id != SEND_THREAD_ID)
- {
- SuspendThread(mainhandle); //中止主线程的运行,模拟中断产生.但没有保存寄存器
- recv_context.ContextFlags = CONTEXT_FULL;
- GetThreadContext(mainhandle, &recv_context); //保存主线程上下文
- SetThreadContext(mainhandle, &send_context); //得到主线程上下文,为切换任务做准备
- cur_thread_id = SEND_THREAD_ID;
- ResumeThread(mainhandle);
- }
- }
- else //启动hd_recv_thread
- {
- if(cur_thread_id != RECV_THREAD_ID)
- {
- SuspendThread(mainhandle); //中止主线程的运行,模拟中断产生.但没有保存寄存器
- send_context.ContextFlags = CONTEXT_FULL;
- GetThreadContext(mainhandle, &send_context); //保存主线程上下文
- SetThreadContext(mainhandle, &recv_context); //得到主线程上下文,为切换任务做准备
- cur_thread_id = RECV_THREAD_ID;
- ResumeThread(mainhandle);
- }
- }
- }
- int main()
- {
- MSG msg;
- SetTimer(NULL, uiTimerID, 1000, TimerFun);
- hd_send_thread = CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE)send_thread_func,
- 0,
- 0,
- 0);
- SuspendThread(hd_send_thread);
- hd_recv_thread = CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE)recv_thread_func,
- 0,
- 0,
- 0);
- SuspendThread(hd_recv_thread);
- DuplicateHandle(GetCurrentProcess(),
- hd_send_thread,
- GetCurrentProcess(),
- &mainhandle,
- 0,
- TRUE,
- 2);
- cur_thread_id = SEND_THREAD_ID;
- ResumeThread(hd_send_thread);
- ResumeThread(hd_recv_thread);
- while(GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
不知道为什么在main函数中,就将hd_send_thread、hd_recv_thread两个线程的上下文保存到send_context、recv_context中,然后再到定时器中断中进行切换就会出错,所以将这部分的代码也放在第一次进定时器中断的时候运行。
转载请注明原文出处,http://www.cnblogs.com/flyingcloude/p/6992343.html
时间: 2024-10-14 10:04:43