呵呵,早说啊,你是想保证当前的线程数量不大于10个是吧 以下代码不能保证当前的线程数刚好是10个,但是能保证当前线程数不会大于10个program Project1;{$APPTYPE CONSOLE}uses SysUtils, Windows; type TMyRecord = record i: Integer; end; MyRecord = ^TMyRecord;var ThreadID: DWORD; //ThreadHandle: THandle; ThreadNum: MyRecord; cs: TRTLCriticalSection;function ThreadPar(p: MyRecord): Integer; stdcall; begin EnterCriticalSection(cs); try Writeln(IntToStr(p.i)); Inc(p.i); finally LeaveCriticalSection(cs); end; Result := 0; end; const ThreadCount = 100; ThreadMax = 10; //注意,这个数字不能大于64var I: Integer; hWork: array[0..ThreadMax - 1] of THandle; dRes, n: DWORD;begin InitializeCriticalSection(cs); GetMem(ThreadNum, SizeOf(TMyRecord)); ThreadNum.i :=0; //先创建 ThreadMax 个线程 for I := 0 to ThreadMax - 1 do hWork[I] := CreateThread(nil, 0, @ThreadPar, ThreadNum, 0, ThreadID); for I := 0 to ThreadCount - ThreadMax - 1 do begin //等待,直到 hWork 中包含的任意一个线程结束为止 dRes := WaitForMultipleObjects(ThreadMax, @hWork[0], False, INFINITE); case dRes of WAIT_TIMEOUT, WAIT_FAILED: Exit; end; n := dRes - WAIT_OBJECT_0; //获得成功结束的线程的句柄在hWork中的索引号 //创建一个新线程,并将线程句柄保存到 hWork 中 hWork[n] := CreateThread(nil, 0, @ThreadPar, ThreadNum, 0, ThreadID); end; WaitForMultipleObjects(ThreadMax, @hWork[0], True, INFINITE); //等待所有线程结束 DeleteCriticalSection(cs); FreeMem(ThreadNum); Readln; //让程序暂停一下,回车就会继续 end.
就你的问题来说,很难保持10个线程。 因为你的例子太简单了,即使不使用等待函数,就是 for i := 0 to 99 do CreateThread(nil,0,@ThreadPar,ThreadNum,0,ThreadID); 这样,也不一定能保证同时执行的线程会有10个。如果你的线程函数足够耗时,那么,我给你的那个例子,基本能保证当前有10个线程在同时执行
1.类似定制版的浏览器。读取指定页面。http://news.baidu.com/然后软件上有个登陆窗口。不是在网页上登陆。直接在软件上用“按钮+文本框”登陆百度。
2.读取某网站的页面内容。获取他最新更新的新闻。并且自动刷新网页。在网页上有新闻的时候。弹出消息对话框。告诉我有最新新闻了。能弹出对话框的同时 要是能播放个音乐什么的最好了 。
3.读取网页指定区域。的指定内容。比如网站上的新闻列表。读出来在软件的Webbrowser控件界面上显示。出来。不是直接是浏览器。不需要读取这个页面。只要网页上的一部分内容就好了。
4.我不要再软件上让人看到百度广告等等垃圾消息。只要新闻。每隔20秒自动刷新一次。弹窗对话框或者语音。提示有新的新闻出来了。看看有没有高手有现成的或者类似的源码的。
发给我邮箱:1617822579(at)qq.com 或者联系我qq# 1617822579
根据你想要的结果,做了小的改动
type
TMyRecord=record
i:Integer;
end;
MyRecord=^TMyRecord;var
ThreadID:DWORD;
ThreadHandle:THandle;
ThreadNum:MyRecord;
cs:TRTLCriticalSection;function ThreadPar(p:MyRecord): DWORD; stdcall;
begin
EnterCriticalSection(cs);
try
Inc(p.i);
Writeln(IntToStr(p.i));
finally
LeaveCriticalSection(cs);
end;
if p.i < 100 then
ThreadHandle :=CreateThread(nil,0,@ThreadPar,ThreadNum,0,ThreadID);
Result := 0;
end;
begin
InitializeCriticalSection(cs);
GetMem(ThreadNum,SizeOf(ThreadNum));
ThreadNum.i :=0;
ThreadHandle :=CreateThread(nil,0,@ThreadPar,ThreadNum,0,ThreadID);
Readln
end.
不过,你的代码中,至少有这个错误
GetMem(ThreadNum,SizeOf(ThreadNum));
这是不对的,因为SizeOf(ThreadNum)永远是4,不管你的结构体是怎么定义的。
之所以在你的程序中没有出问题,那是因为你的 TMyRecord 结构体刚好是4,所以没有出错误
如果你定义一个size大于4的,而你去访问这个结构体中排在后面的数据,那肯定会出问题。
正确的应该是
GetMem(ThreadNum,SizeOf(TMyRecord));
另外,你这不能算是多线程并发,你的程序虽然使用了线程,但是都是前一个线程马上结束了,才启动下一个线程,你的这种写法,更像是接力赛。另外
Writeln()函数默认的是向标准控制台输出,这个函数是否能用在多线程环境下,还有待研究。
WaitForSingleObject
函数使用上可能存在误解
从你的代码上看,是在等待 ThreadHandle 线程句柄,而你的每一个线程函数在创建新线程的时候,都会改变这个变量的值,你是不是认为,这样WaitForSingleObject函数就能一直等待,直到最后一个线程结束才会返回?
这种使用方式是错误的!
ThreadHandle :=CreateThread(nil,0,@ThreadPar,ThreadNum,0,ThreadID);
WaitForSingleObject(ThreadHandle,INFINITE);
这个WaitForSingleObject函数一旦被调用了,他就只会等待调用的时候指定的这个线程,即使你在线程中改变了ThreadHandle的值,也不会影响到WaitForSingleObject函数。
因此,你创建的第一个线程结束了,那么WaitForSingleObject就会返回
换句话说,你创建的第二个线程可能还没有来得及执行,你的程序就已经结束了。或许,这就是你为什么不能输出 1 - 100的原因吧。
我想实现的是创建多个线程一直将想要输出的数值显示到控制台上边
在begin...end;中间启动线程,在线程调用的函数体内检测线程数量是否小于10,如果小于10的话,会自动再创建相应的线程数量,使其不小于10!能否实现呢?希望能得到您的代码...谢谢
以下代码不能保证当前的线程数刚好是10个,但是能保证当前线程数不会大于10个program Project1;{$APPTYPE CONSOLE}uses
SysUtils,
Windows;
type
TMyRecord = record
i: Integer;
end;
MyRecord = ^TMyRecord;var
ThreadID: DWORD;
//ThreadHandle: THandle;
ThreadNum: MyRecord;
cs: TRTLCriticalSection;function ThreadPar(p: MyRecord): Integer; stdcall;
begin
EnterCriticalSection(cs);
try
Writeln(IntToStr(p.i));
Inc(p.i);
finally
LeaveCriticalSection(cs);
end;
Result := 0;
end;
const
ThreadCount = 100;
ThreadMax = 10; //注意,这个数字不能大于64var
I: Integer;
hWork: array[0..ThreadMax - 1] of THandle;
dRes, n: DWORD;begin
InitializeCriticalSection(cs);
GetMem(ThreadNum, SizeOf(TMyRecord));
ThreadNum.i :=0; //先创建 ThreadMax 个线程
for I := 0 to ThreadMax - 1 do
hWork[I] := CreateThread(nil, 0, @ThreadPar, ThreadNum, 0, ThreadID); for I := 0 to ThreadCount - ThreadMax - 1 do
begin
//等待,直到 hWork 中包含的任意一个线程结束为止
dRes := WaitForMultipleObjects(ThreadMax, @hWork[0], False, INFINITE);
case dRes of
WAIT_TIMEOUT, WAIT_FAILED: Exit;
end;
n := dRes - WAIT_OBJECT_0; //获得成功结束的线程的句柄在hWork中的索引号
//创建一个新线程,并将线程句柄保存到 hWork 中
hWork[n] := CreateThread(nil, 0, @ThreadPar, ThreadNum, 0, ThreadID);
end;
WaitForMultipleObjects(ThreadMax, @hWork[0], True, INFINITE); //等待所有线程结束
DeleteCriticalSection(cs);
FreeMem(ThreadNum);
Readln; //让程序暂停一下,回车就会继续
end.
因为你的例子太简单了,即使不使用等待函数,就是
for i := 0 to 99 do
CreateThread(nil,0,@ThreadPar,ThreadNum,0,ThreadID);
这样,也不一定能保证同时执行的线程会有10个。如果你的线程函数足够耗时,那么,我给你的那个例子,基本能保证当前有10个线程在同时执行
这句话,使用GetMem(ThreadNum, LengTh(ThreadNum);可以嘛?