我现在用了多线程开发了Socket通讯,如果并发的数据量大的话,起线程会失败,怎样来判断起线程是否成功?急

解决方案 »

  1.   

    失败在哪?是无法启动线程?还是 Socket 失败?
    建议
    tryexceptend;
      

  2.   

    是无法启动线程.但是也没有异常发生.resume不了.
      

  3.   

    constructor TSecuReqThread.Create(iListen, iConnect: Integer; iBranch: Smallint;
        FieldsList: TStringList; iLength: Integer);
    begin
        inherited create(true);
        bPack := TPack.Create(True);
        sPack := TPack.Create(True);
        bUnPack := TUnPack.Create(True);
        Listen := iListen;
        Connect := iConnect;
        Len := iLength;
        TransLog := sLog;
        LogRec := TTransLogObj.create;
        self.secuFieldList := TStringList.Create;
        self.SecuFieldList.AddStrings(FieldsList);
        FieldList := TStringList.Create;
        ClientSocket := TClientSocket.Create(nil);
        ClientSocket.ClientType := ctBlocking;
        self.FreeOnTerminate := True;
        resume;
    end;这个就是线程初始化的源代码,帮我看看有什么问题?
      

  4.   

    TPack/TUnPack/TTransLogObj各是什么啊?
      

  5.   

    看这段初始化代码,没什么问题Execute代码呢?
      

  6.   

    建议楼主,线程没有进入到 Execute 的时候,最好不要创建不必要的资源,
    例如:你上面代码中的 ClientSocket。
    你可以创建 100 个线程,但都是挂起的,这个时候如果你所用到的资源都在 Create 方法中已经创建了,那样是不是太浪费了?把它们写在 Execute 的方法中,最后在 Free 掉,这样能保存你系统资源的回收和再利用。如果你的线程量特别大的时候,特别有用,估记你十有八九是资源不足了。
    另外,最好是把 Execute  代码也贴出来。
      

  7.   

    //主线程procedure TSecuReqThread.Execute;
    var
        sItem: string;
        Ret, tmpRetCode: integer;
    begin
        sItem := iSTradeNo;
        ConvertDict(sItem, 'Secu_Bank', 0);
        sItem := Copy(sItem, 1, 6);
        iBTradeNo := sItem;
        sItem := iSTradeNo;
        ConvertDict(sItem, 'Code_Name', 0);
        self.transName := sItem;
        self.Serial := GetNextSerial('1');
        logRec.setSerialNum(self.serial);
        logRec.setTransID(iSTradeNo);
        logRec.setTransName(self.transName);
        try
            SecuNo := SecuFieldList.Values['sOrganId'];
            self.ReqSerial := SecuFieldList.Values['ExSerial'];
            logRec.setReq('S');
            logRec.setSecuBranch(RegReadStr('证券设置\券商设置\' + SecuNo, 'sz营业部简称'));
            logRec.setTransID(SecuFieldList.Values['FunctionId']);
            PacketRequest(StrToIntDef(iSTradeNo, 0), 0);
            transPkg := #13#10 + '[' + GetTime + '] 请求包=【' + sRequest + '】' + #13#10;
            Ret := DataSend(bPack.Buffer);
            tmpRetCode := RetCode;
            if Ret <> ERR_SUCCESS then
            begin
                case Ret of
                    ERR_SOCK_CONN:
                        RetMsg := '连接失败';
                    ERR_SOCK_SEND:
                        RetMsg := '发送失败';
                    ERR_SOCK_RECV:
                        RetMsg := '接收失败';
                    ERR_PACK_DECODE:
                        RetMsg := '解包失败';
                end;
                RetCode :=Ret;
                CnvErrorRet(StrToIntDef(iSTradeNo, 0), ReqSerial, IntToStr(Ret), RetMsg);
                transPkg := transPkg + '[' + GetTime + '] 应答包=【' + bAnswer + '】' + #13#10;
                ReturnToCommX;
                RetCode := Ret;
                GernalLog;
                exit;
            end;
            RetCode := tmpRetCode;
            if RetCode <> 0 then
            begin
                RetMsg := '解包:应答包结构错';
                CnvErrorRet(StrToIntDef(iSTradeNo, 0), ReqSerial, IntToStr(Ret), RetMsg);
                transPkg := transPkg + '[' + GetTime + '] 应答包=【' + bAnswer + '】' + #13#10;
                ReturnToCommX;
                GernalLog;
                exit;
            end;        RetCode := bUnPack.Sections[0].FieldByName('ErrorNo').AsInteger;
            RetMsg := bUnPack.Sections[0].FieldByName('ErrorInfo').AsString;
            if RetCode = 0 then
                PacketAnswer(StrToIntDef(iSTradeNo, 0), 1)
            else
            begin
                if (RetCode = 70010) or (RetCode = 70009) then //余额不足
                    RetCode := 1423;
                CnvErrorRet(StrToIntDef(iSTradeNo, 0), ReqSerial, IntToStr(RetCode), RetMsg);
            end;
            transPkg := transPkg + '[' + GetTime + '] 应答包=【' + bAnswer + '】' + #13#10;
            ReturnToCommX;
            GernalLog;
        except    end;
        inherited;
    end;
      

  8.   

    主线程应该没什么问题的,因为Create以后,就根本没执行到Execute,就已经自动终止了.我在
    Create的第一行就已经加了调试语句了.
      

  9.   

    TSecuReqThread 线程是从哪个类派生出来的,因为我注意到你在 Execute 最后调用了 Inherited 是不是上层还定义了另一个线程对象,另外,我注意到从你这段 Execute 代码看来,你没有用到任何临界段或信号量之类的东西,不知道是不是封装到其它的地方了,这么大量的并发处理,怎么不用临界面或信号量呢?你如何保证线程的同步或者共享访问数据方面的问题呢?
    这么多线程难道没有同时访问同一块内存、数据或者对象的时候吗?这块内存、数据或者对象是线程安全的吗?另外不知道你的程序是否要和程序的界面通讯,如果用的话,线程也可能会失效,因为 VCL 控件本身是不支持多线程的,你需要用 SendMessage 或 线程对象本身的 Synchronize 方法来与界面通讯,如果你没有用到界面那就另说了。