这个多线程程序错在哪儿?(书上的一个例子) ( 积分: 300 )

  • 主题发起人 主题发起人 刘麻子
  • 开始时间 开始时间

刘麻子

Unregistered / Unconfirmed
GUEST, unregistred user!
这是《Windows核心编程》上的一个例子,用PASCAL写了一遍,发现在很容易出现这样的状
况:多次按下Suspend按钮之后,主线程挂起,并且新线程里面的MessageBox弹不出来。。
随后又测试了原书光盘中的C程序,也是同样的情况,不知哪里有问题? PASCAL代码如下:
program SchedLab;
{$R 'SchedLab.res' 'SchedLab.rc'}
uses
Windows, Messages;
const
// 线程权限
THREAD_SUSPEND_RESUME = $0002;
// 优先级类
BELOW_NORMAL_PRIORITY_CLASS = $4000;
ABOVE_NORMAL_PRIORITY_CLASS = $8000;
// 模板ID
IDD_SCHEDLAB = 101;
// 图标ID
IDI_SCHEDLAB = 103;
// 控件ID
IDC_PROCESSPRIORITYCLASS = 1015;
IDC_THREADRELATIVEPRIORITY = 1016;
IDC_SLEEPTIME = 1017;
IDC_SUSPEND = 1018;
IDC_WORK = 1020;
// 线程函数
function ThreadFunc(pvParam: Pointer): Integer;
var
hThreadPrimary: THandle;
begin
// 挂起主线程
hThreadPrimary := THandle(pvParam);
SuspendThread(hThreadPrimary);
// 弹出消息框
MessageBox(GetActiveWindow(),
'The Primary thread is suspended.'#13#10 +
'It no longer responds to input and produces no output.'#13#10 +
'Press OK to resume the primary thread &
exit this secondary thread.'#13#10,
'SchedLab', 0);
// 恢复主线程
ResumeThread(hThreadPrimary);
CloseHandle(hThreadPrimary);
// 再恢复按钮
EnableWindow(GetDlgItem(FindWindow(nil, 'Scheduling Lab'), IDC_SUSPEND), TRUE);

Result := 0;
end;

// 对话框WM_INITDIALOG消息处理
function Dlg_OnInitDialog(hWnd, hWndFocus: HWND;
lParam: LPARAM): BOOL;
var
hWndCtl: LongWord;
// HWND
n, nNormal: Integer;
dwpc: DWORD;
begin
// 设置对话框图标
SendMessage(hWnd, WM_SETICON, ICON_BIG, LoadIcon(HInstance, MakeIntResource(IDI_SCHEDLAB)));
SendMessage(hWnd, WM_SETICON, ICON_SMALL, LoadIcon(HInstance, MakeIntResource(IDI_SCHEDLAB)));

// 1.
// 基本优先级列表
hWndCtl := GetDlgItem(hWnd, IDC_PROCESSPRIORITYCLASS);
// 添加'高'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('High')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, HIGH_PRIORITY_CLASS);
// 当前基本优先级
dwpc := GetPriorityClass(GetCurrentProcess());
// 支持新的优先级
if SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS) then
begin
// 恢复基本优先级
SetPriorityClass(GetCurrentProcess(), dwpc);
// 添加'高于正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Above normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, ABOVE_NORMAL_PRIORITY_CLASS);
// 支持新的优先级
dwpc := 0;
end;

// 添加'正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, NORMAL_PRIORITY_CLASS);
nNormal := n;
// 支持新的优先级, 则添加'低于正常'优先级
if (dwpc = 0) then
begin
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Below normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, BELOW_NORMAL_PRIORITY_CLASS);
end;

// 添加'空闲'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Idle')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, IDLE_PRIORITY_CLASS);
// 选中'正常'优先级
SendMessage(hWndCtl, CB_SETCURSEL, nNormal, 0);

// 2.
// 线程优先级列表
hWndCtl := GetDlgItem(hWnd, IDC_THREADRELATIVEPRIORITY);
// 添加'关键时间'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Time critical')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_TIME_CRITICAL);
// 添加'最高'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Highest')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_HIGHEST);
// 添加'高于正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Above normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_ABOVE_NORMAL);
// 添加'正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_NORMAL);
nNormal := n;
// 添加'低于正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Below normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_BELOW_NORMAL);
// 添加'最低'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Lowest')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_LOWEST);
// 添加'空闲'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Idle')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_IDLE);
// 选中'正常'优先级
SendMessage(hWndCtl, CB_SETCURSEL, nNormal, 0);

// 限制Edit长度
SendMessage(GetDlgItem(hWnd, IDC_SLEEPTIME), EM_LIMITTEXT, 4, 0);
// 接受默认焦点
Result := TRUE;
end;

// 对话框WM_COMMAND消息处理
procedure Dlg_OnCommand(hWnd: HWND;
id: Integer;
hWndCtl: HWND;
codeNotify: UINT);
var
hThreadPrimary: THandle;
dwThreadID: DWORD;
begin
case (id) of
IDCANCEL: // 要求关闭
begin
PostQuitMessage(0);
end;

IDC_PROCESSPRIORITYCLASS: // 基本优先级
if (codeNotify = CBN_SELCHANGE) then
begin
SetPriorityClass(GetCurrentProcess(),
SendMessage(hWndCtl, CB_GETITEMDATA, SendMessage(hWndCtl, CB_GETCURSEL, 0, 0), 0));
end;

IDC_THREADRELATIVEPRIORITY: // 线程优先级
if (codeNotify = CBN_SELCHANGE) then
begin
SetThreadPriority(GetCurrentThread(),
SendMessage(hWndCtl, CB_GETITEMDATA, SendMessage(hWndCtl, CB_GETCURSEL, 0, 0), 0));
end;

IDC_SUSPEND: // 挂起
begin
// 建立线程前禁用按钮
EnableWindow(hWndCtl, FALSE);
// 虚拟句柄 -> 实句柄
DuplicateHandle(
GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), @hThreadPrimary,
THREAD_SUSPEND_RESUME, FALSE, DUPLICATE_SAME_ACCESS);
// 建立线程并释放对象
CloseHandle(begin
Thread(nil, 0, @ThreadFunc, Pointer(hThreadPrimary), 0, dwThreadID));
end;
end;
end;

// 对话框消息处理回调
function Dlg_Proc(hWnd: HWND;
uMsg: UINT;
wParam: WPARAM;
lParam: LPARAM): BOOL;
stdcall;
begin
Result := FALSE;
case (uMsg) of
WM_INITDIALOG:
Result := SetWindowLong(hWnd, DWL_MSGRESULT, Longint(Dlg_OnInitDialog(hWnd, wParam, lParam))) <> 0;
WM_COMMAND:
Dlg_OnCommand(hWnd, LOWORD(wParam), lParam, HIWORD(wParam));
end;
end;

// 程序主线程入口
var
hWnd, hWndWork: LongWord;
// HWND
Msg: TMsg;
fQuit: BOOL = FALSE;
s_n: Integer = -1;
sz: array[0..20] of Char;
nSleep: Integer;
begin
// 建立窗口
hWnd := CreateDialog(HInstance, MakeIntResource(IDD_SCHEDLAB), 0, @Dlg_Proc);
// 消息循环
while (not fQuit)do
begin
// 从队列取到消息
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
// 处理'对话框消息'
if (not IsDialogMessage(hWnd, Msg)) then
begin
if (Msg.message <> WM_QUIT) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end else
fQuit := TRUE;
// 循环结束标志
end;
end else
begin
// 添加数字字符串至ListBox
Inc(s_n);
wvsprintf(sz, '%u', @s_n);
hWndWork := GetDlgItem(hWnd, IDC_WORK);
SendMessage(hWndWork, LB_SETCURSEL, SendMessage(hWndWork, LB_ADDSTRING, 0, Integer(@sz[0])), 0);
// 移除ListBox多余项目
while (SendMessage(hWndWork, LB_GETCOUNT, 0, 0) > 100)do
SendMessage(hWndWork, LB_DELETESTRING, 0, 0);
// 挂起Edit指定毫秒数
nSleep := GetDlgItemInt(hWnd, IDC_SLEEPTIME, PBOOL(nil)^, FALSE);
if (nSleep >= 1) and (nSleep <= 9999) then
Sleep(nSleep);
end;
end;

// 清除窗口
DestroyWindow(hWnd);
end.
 
这是《Windows核心编程》上的一个例子,用PASCAL写了一遍,发现在很容易出现这样的状
况:多次按下Suspend按钮之后,主线程挂起,并且新线程里面的MessageBox弹不出来。。
随后又测试了原书光盘中的C程序,也是同样的情况,不知哪里有问题? PASCAL代码如下:
program SchedLab;
{$R 'SchedLab.res' 'SchedLab.rc'}
uses
Windows, Messages;
const
// 线程权限
THREAD_SUSPEND_RESUME = $0002;
// 优先级类
BELOW_NORMAL_PRIORITY_CLASS = $4000;
ABOVE_NORMAL_PRIORITY_CLASS = $8000;
// 模板ID
IDD_SCHEDLAB = 101;
// 图标ID
IDI_SCHEDLAB = 103;
// 控件ID
IDC_PROCESSPRIORITYCLASS = 1015;
IDC_THREADRELATIVEPRIORITY = 1016;
IDC_SLEEPTIME = 1017;
IDC_SUSPEND = 1018;
IDC_WORK = 1020;
// 线程函数
function ThreadFunc(pvParam: Pointer): Integer;
var
hThreadPrimary: THandle;
begin
// 挂起主线程
hThreadPrimary := THandle(pvParam);
SuspendThread(hThreadPrimary);
// 弹出消息框
MessageBox(GetActiveWindow(),
'The Primary thread is suspended.'#13#10 +
'It no longer responds to input and produces no output.'#13#10 +
'Press OK to resume the primary thread &amp;
exit this secondary thread.'#13#10,
'SchedLab', 0);
// 恢复主线程
ResumeThread(hThreadPrimary);
CloseHandle(hThreadPrimary);
// 再恢复按钮
EnableWindow(GetDlgItem(FindWindow(nil, 'Scheduling Lab'), IDC_SUSPEND), TRUE);

Result := 0;
end;

// 对话框WM_INITDIALOG消息处理
function Dlg_OnInitDialog(hWnd, hWndFocus: HWND;
lParam: LPARAM): BOOL;
var
hWndCtl: LongWord;
// HWND
n, nNormal: Integer;
dwpc: DWORD;
begin
// 设置对话框图标
SendMessage(hWnd, WM_SETICON, ICON_BIG, LoadIcon(HInstance, MakeIntResource(IDI_SCHEDLAB)));
SendMessage(hWnd, WM_SETICON, ICON_SMALL, LoadIcon(HInstance, MakeIntResource(IDI_SCHEDLAB)));

// 1.
// 基本优先级列表
hWndCtl := GetDlgItem(hWnd, IDC_PROCESSPRIORITYCLASS);
// 添加'高'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('High')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, HIGH_PRIORITY_CLASS);
// 当前基本优先级
dwpc := GetPriorityClass(GetCurrentProcess());
// 支持新的优先级
if SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS) then
begin
// 恢复基本优先级
SetPriorityClass(GetCurrentProcess(), dwpc);
// 添加'高于正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Above normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, ABOVE_NORMAL_PRIORITY_CLASS);
// 支持新的优先级
dwpc := 0;
end;

// 添加'正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, NORMAL_PRIORITY_CLASS);
nNormal := n;
// 支持新的优先级, 则添加'低于正常'优先级
if (dwpc = 0) then
begin
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Below normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, BELOW_NORMAL_PRIORITY_CLASS);
end;

// 添加'空闲'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Idle')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, IDLE_PRIORITY_CLASS);
// 选中'正常'优先级
SendMessage(hWndCtl, CB_SETCURSEL, nNormal, 0);

// 2.
// 线程优先级列表
hWndCtl := GetDlgItem(hWnd, IDC_THREADRELATIVEPRIORITY);
// 添加'关键时间'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Time critical')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_TIME_CRITICAL);
// 添加'最高'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Highest')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_HIGHEST);
// 添加'高于正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Above normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_ABOVE_NORMAL);
// 添加'正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_NORMAL);
nNormal := n;
// 添加'低于正常'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Below normal')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_BELOW_NORMAL);
// 添加'最低'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Lowest')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_LOWEST);
// 添加'空闲'优先级
n := SendMessage(hWndCtl, CB_ADDSTRING, 0, Integer(PChar('Idle')));
SendMessage(hWndCtl, CB_SETITEMDATA, n, THREAD_PRIORITY_IDLE);
// 选中'正常'优先级
SendMessage(hWndCtl, CB_SETCURSEL, nNormal, 0);

// 限制Edit长度
SendMessage(GetDlgItem(hWnd, IDC_SLEEPTIME), EM_LIMITTEXT, 4, 0);
// 接受默认焦点
Result := TRUE;
end;

// 对话框WM_COMMAND消息处理
procedure Dlg_OnCommand(hWnd: HWND;
id: Integer;
hWndCtl: HWND;
codeNotify: UINT);
var
hThreadPrimary: THandle;
dwThreadID: DWORD;
begin
case (id) of
IDCANCEL: // 要求关闭
begin
PostQuitMessage(0);
end;

IDC_PROCESSPRIORITYCLASS: // 基本优先级
if (codeNotify = CBN_SELCHANGE) then
begin
SetPriorityClass(GetCurrentProcess(),
SendMessage(hWndCtl, CB_GETITEMDATA, SendMessage(hWndCtl, CB_GETCURSEL, 0, 0), 0));
end;

IDC_THREADRELATIVEPRIORITY: // 线程优先级
if (codeNotify = CBN_SELCHANGE) then
begin
SetThreadPriority(GetCurrentThread(),
SendMessage(hWndCtl, CB_GETITEMDATA, SendMessage(hWndCtl, CB_GETCURSEL, 0, 0), 0));
end;

IDC_SUSPEND: // 挂起
begin
// 建立线程前禁用按钮
EnableWindow(hWndCtl, FALSE);
// 虚拟句柄 -> 实句柄
DuplicateHandle(
GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), @hThreadPrimary,
THREAD_SUSPEND_RESUME, FALSE, DUPLICATE_SAME_ACCESS);
// 建立线程并释放对象
CloseHandle(begin
Thread(nil, 0, @ThreadFunc, Pointer(hThreadPrimary), 0, dwThreadID));
end;
end;
end;

// 对话框消息处理回调
function Dlg_Proc(hWnd: HWND;
uMsg: UINT;
wParam: WPARAM;
lParam: LPARAM): BOOL;
stdcall;
begin
Result := FALSE;
case (uMsg) of
WM_INITDIALOG:
Result := SetWindowLong(hWnd, DWL_MSGRESULT, Longint(Dlg_OnInitDialog(hWnd, wParam, lParam))) <> 0;
WM_COMMAND:
Dlg_OnCommand(hWnd, LOWORD(wParam), lParam, HIWORD(wParam));
end;
end;

// 程序主线程入口
var
hWnd, hWndWork: LongWord;
// HWND
Msg: TMsg;
fQuit: BOOL = FALSE;
s_n: Integer = -1;
sz: array[0..20] of Char;
nSleep: Integer;
begin
// 建立窗口
hWnd := CreateDialog(HInstance, MakeIntResource(IDD_SCHEDLAB), 0, @Dlg_Proc);
// 消息循环
while (not fQuit)do
begin
// 从队列取到消息
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
// 处理'对话框消息'
if (not IsDialogMessage(hWnd, Msg)) then
begin
if (Msg.message <> WM_QUIT) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end else
fQuit := TRUE;
// 循环结束标志
end;
end else
begin
// 添加数字字符串至ListBox
Inc(s_n);
wvsprintf(sz, '%u', @s_n);
hWndWork := GetDlgItem(hWnd, IDC_WORK);
SendMessage(hWndWork, LB_SETCURSEL, SendMessage(hWndWork, LB_ADDSTRING, 0, Integer(@sz[0])), 0);
// 移除ListBox多余项目
while (SendMessage(hWndWork, LB_GETCOUNT, 0, 0) > 100)do
SendMessage(hWndWork, LB_DELETESTRING, 0, 0);
// 挂起Edit指定毫秒数
nSleep := GetDlgItemInt(hWnd, IDC_SLEEPTIME, PBOOL(nil)^, FALSE);
if (nSleep >= 1) and (nSleep <= 9999) then
Sleep(nSleep);
end;
end;

// 清除窗口
DestroyWindow(hWnd);
end.
 
完整代码在此下载,欢迎帮忙测试,看看在您那里是否有问题?
http://vipdown1.axdisk.cn/liumazi/Temp/07-SchedLab.rar
 
帮顶。。。学习!
 
上面那个链接暂时下载不了,哎,他们服务器好像出问题了,等等吧。 :~(
 
这里也可以下载,不过有时限的。
http://upserver3.ys168.com/ys168up/D1/Ys.aspx?f=07-SchedLab.rary68z74f8b3f8b2f9b2z95b0f8b2b3f9b2f5f9b5b1f9f8b7f6e14z97e14e24b1b0f2f9b2f9b6f6b6b6z
 
我正在编写基于SOCKET网络程序,发现多线程的队列处理确实麻烦,帮您顶一下。
 
谢谢,谢谢,有空的朋友请帮忙测试一下,在您的机器上,
多次按下Suspend按钮,是否出问题?
我这边在xp有问题,在98暂时没问题,没有装2000。 :~)
 
在2000中多按了几下suspend程序死掉了
 
谢谢 bamlan兄 。
 
呵呵,就是你也有不会的?
顶..........................
 
不过设置了sleep后按了很久也没出问题!
 
对的,主线程Sleep()就很难出错了。 :~)
 
服务器好了,在此下载 http://vipdown1.axdisk.cn/liumazi/Temp/07-SchedLab.rar
 
SuspendThread(hThreadPrimary);
// 弹出消息框
MessageBox(GetActiveWindow(),
'The Primary thread is suspended.'#13#10 +
'It no longer responds to input and produces no output.'#13#10 +
'Press OK to resume the primary thread &amp;
exit this secondary thread.'#13#10,
'SchedLab', 0);
// 恢复主线程
ResumeThread(hThreadPrimary);
-------------------------------------------
线程SuspendThread了, 还能MessageBox吗?
delphi中调试的时候,在MessageBox这里下断点,如果线程立即Suspend的话,就会出现不能执行MessageBox下面的代码了,也就不会ResumeThread了.甚至有时会出现,MessageBox的对话框刚显示,还没来得及显示'The Primary thread is suspended...'这些文字的时候程序死掉.因为在这时,线程Suspend了...
但为什么该线程停止了,主线程也跟着死了, 可能因为用的是CreateDialog,而不是CreateWindow吧, 猜的. :)
 
to 刘:
我对多线程和自己写消息循环机制不太熟,但我调试你的程序时,发现把“ 弹出消息框”的代码屏蔽掉,就不会出现你说的问题,不知道这样能不能给你一些帮助?
对了,你能给我看看你写的资源文件的内容吗?我的QQ叫“傲视无双”。
 
看来我正在写的时候,楼上的也正在写关于“ 弹出消息框”的的这个问题,呵呵,同感,发完后,我才看到,楼上的比我早了几分钟。
对了,我的系统是XP+sp2 CPU AMD
 
刘麻子的东西,友情顶。
我在 Win2003 下测试,出现无法响应,但有时能行。
楼上有人解释了,所以我没看,我今天才学用多线程的。
 
我改了一下代码,请测试:
// 线程函数
function ThreadFunc(pvParam: Pointer): Integer;
var
hThreadPrimary: THandle;
begin
// 挂起主线程
hThreadPrimary := THandle(pvParam);
SuspendThread(hThreadPrimary);
// 弹出消息框
MessageBox(GetActiveWindow(),
'The Primary thread is suspended.'#13#10 +
'It no longer responds to input and produces no output.'#13#10 +
'Press OK to resume the primary thread &amp;
exit this secondary thread.'#13#10,
'SchedLab', 0);
// 恢复主线程
ResumeThread(hThreadPrimary);
CloseHandle(hThreadPrimary);
// 再恢复按钮
//EnableWindow(GetDlgItem(FindWindow(nil, 'Scheduling Lab'), IDC_SUSPEND), TRUE);
//还是交给主线程吧!


Result := 0;
end;

// 对话框WM_COMMAND消息处理
procedure Dlg_OnCommand(hWnd: HWND;
id: Integer;
hWndCtl: HWND;
codeNotify: UINT);
var
hThreadPrimary: THandle;
dwThreadID: DWORD;
hThread: THandle;
begin
case (id) of
IDCANCEL: // 要求关闭
begin
PostQuitMessage(0);
end;

IDC_PROCESSPRIORITYCLASS: // 基本优先级
if (codeNotify = CBN_SELCHANGE) then
begin
SetPriorityClass(GetCurrentProcess(),
SendMessage(hWndCtl, CB_GETITEMDATA, SendMessage(hWndCtl, CB_GETCURSEL, 0, 0), 0));
end;

IDC_THREADRELATIVEPRIORITY: // 线程优先级
if (codeNotify = CBN_SELCHANGE) then
begin
SetThreadPriority(GetCurrentThread(),
SendMessage(hWndCtl, CB_GETITEMDATA, SendMessage(hWndCtl, CB_GETCURSEL, 0, 0), 0));
end;

IDC_SUSPEND: // 挂起
begin
// 建立线程前禁用按钮
EnableWindow(hWndCtl, FALSE);
// 虚拟句柄 -> 实句柄
DuplicateHandle(
GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), @hThreadPrimary,
THREAD_SUSPEND_RESUME, FALSE, DUPLICATE_SAME_ACCESS);
// 建立线程并释放对象
hThread := begin
Thread(nil, 0, @ThreadFunc, Pointer(hThreadPrimary), 0, dwThreadID);
//增加等待第二个线程结束的代码
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
//自己的事还是自己来办吧!
EnableWindow(hWndCtl, True);

end;
end;
end;
 
后退
顶部