本帖最后由 WinSockCF 于 2011-03-02 13:29:29 编辑

解决方案 »

  1.   

    procedure ThreadPar(p:MyRecord);stdcall;->function ThreadPar(p: Pointer): DWORD; stdcall;// 是个 function,有返回值, 参数为Pointer 
      

  2.   

    ThreadNum 是全局变量,不传进函数也行,直接可调用.
      

  3.   

    http://news.baidu.com/我想写个程序。大概的功能是:
    1.类似定制版的浏览器。读取指定页面。http://news.baidu.com/然后软件上有个登陆窗口。不是在网页上登陆。直接在软件上用“按钮+文本框”登陆百度。
    2.读取某网站的页面内容。获取他最新更新的新闻。并且自动刷新网页。在网页上有新闻的时候。弹出消息对话框。告诉我有最新新闻了。能弹出对话框的同时 要是能播放个音乐什么的最好了 。
    3.读取网页指定区域。的指定内容。比如网站上的新闻列表。读出来在软件的Webbrowser控件界面上显示。出来。不是直接是浏览器。不需要读取这个页面。只要网页上的一部分内容就好了。
    4.我不要再软件上让人看到百度广告等等垃圾消息。只要新闻。每隔20秒自动刷新一次。弹窗对话框或者语音。提示有新的新闻出来了。看看有没有高手有现成的或者类似的源码的。
    发给我邮箱:1617822579(at)qq.com 或者联系我qq# 1617822579
      

  4.   


    根据你想要的结果,做了小的改动
    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.
      

  5.   

    你并没有说你的程序到底出了什么错误。
    不过,你的代码中,至少有这个错误
     GetMem(ThreadNum,SizeOf(ThreadNum));
    这是不对的,因为SizeOf(ThreadNum)永远是4,不管你的结构体是怎么定义的。
    之所以在你的程序中没有出问题,那是因为你的 TMyRecord 结构体刚好是4,所以没有出错误
    如果你定义一个size大于4的,而你去访问这个结构体中排在后面的数据,那肯定会出问题。
    正确的应该是
     GetMem(ThreadNum,SizeOf(TMyRecord));
    另外,你这不能算是多线程并发,你的程序虽然使用了线程,但是都是前一个线程马上结束了,才启动下一个线程,你的这种写法,更像是接力赛。另外
    Writeln()函数默认的是向标准控制台输出,这个函数是否能用在多线程环境下,还有待研究。
      

  6.   

    还有一个是你对
    WaitForSingleObject
    函数使用上可能存在误解
    从你的代码上看,是在等待 ThreadHandle 线程句柄,而你的每一个线程函数在创建新线程的时候,都会改变这个变量的值,你是不是认为,这样WaitForSingleObject函数就能一直等待,直到最后一个线程结束才会返回?
    这种使用方式是错误的!
    ThreadHandle :=CreateThread(nil,0,@ThreadPar,ThreadNum,0,ThreadID);
    WaitForSingleObject(ThreadHandle,INFINITE);
    这个WaitForSingleObject函数一旦被调用了,他就只会等待调用的时候指定的这个线程,即使你在线程中改变了ThreadHandle的值,也不会影响到WaitForSingleObject函数。
    因此,你创建的第一个线程结束了,那么WaitForSingleObject就会返回
    换句话说,你创建的第二个线程可能还没有来得及执行,你的程序就已经结束了。或许,这就是你为什么不能输出 1 - 100的原因吧。
      

  7.   


    我想实现的是创建多个线程一直将想要输出的数值显示到控制台上边
    在begin...end;中间启动线程,在线程调用的函数体内检测线程数量是否小于10,如果小于10的话,会自动再创建相应的线程数量,使其不小于10!能否实现呢?希望能得到您的代码...谢谢
      

  8.   

    呵呵,早说啊,你是想保证当前的线程数量不大于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.
      

  9.   

    就你的问题来说,很难保持10个线程。
    因为你的例子太简单了,即使不使用等待函数,就是 
    for i := 0 to 99 do 
     CreateThread(nil,0,@ThreadPar,ThreadNum,0,ThreadID);
    这样,也不一定能保证同时执行的线程会有10个。如果你的线程函数足够耗时,那么,我给你的那个例子,基本能保证当前有10个线程在同时执行
      

  10.   

    你的建线程的临界根本无法在PRINT的同时,其它线程可以建立和执行,还不如一个FOR语句.楼上有人说过,你的一执行就挂掉了,难以保持10个线程同时存在.除非你的线程的生命周期较长..
      

  11.   

    GetMem(ThreadNum, SizeOf(TMyRecord));
    这句话,使用GetMem(ThreadNum, LengTh(ThreadNum);可以嘛?
      

  12.   

    如果要生命周期长一点的话,可以用数组存你的ThreadID,还有一个INT变量,可以让它执行多次.当然在封装好的线程类中较容易实现.
      

  13.   

    将线程中的代码量弄的大一些.能保障线程的生命周期长一些就可以了!在控制台中,也可以使用TThread类的!可以试着运用一下.uses Classes;