2014-06-10 5 views
5

मैं TThread में कस्टम स्टैक आकार कैसे सेट कर सकता हूं? मैं TThread के निर्माता को पुन: पेश करने की कोशिश कर रहा हूं लेकिन यह कहता है कि ThreadProc अभी भी System.Classes में ठीक है।टीटीएचड में स्टैक आकार कैसे सेट करें?

type 
    TThreadHelper = class helper for TThread 
    constructor Create(const CreateSuspended: Boolean = False; const StackSize: Integer = 0); reintroduce; 
end; 

{ TThreadHelper } 

constructor TThreadHelper.Create(const CreateSuspended: Boolean; const StackSize: Integer); 
begin 
    Self.FSuspended := not Self.FExternalThread; 
    Self.FCreateSuspended := CreateSuspended and not Self.FExternalThread; 
    if not Self.FExternalThread then 
    begin 
    Self.FHandle := BeginThread(nil, StackSize, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, Self.FThreadID); 
    if Self.FHandle = 0 then 
    raise EThread.CreateResFmt(@SThreadCreateError, [SysErrorMessage(GetLastError)]); 
    end 
    else 
    begin 
    Self.FHandle := Winapi.Windows.GetCurrentThread; 
    Self.FThreadId := GetCurrentThreadId; 
    end; 
end; 

[dcc32 त्रुटि] Project5.dpr (29): E2003 अघोषित पहचानकर्ता: 'ThreadProc'

+0

'ThreadProc' समारोह सार्वजनिक उपयोग के लिए नहीं है। यह यूनिट के 'इंटरफ़ेस' भाग में भी परिभाषित किया गया होगा। इसलिए संकलक इसे नहीं देख सकता है। – TLama

उत्तर

7

मुझे नहीं पता, अगर आप धागे के निर्माण के बाद स्टैक आकार सेट कर सकते हैं। शायद SetThreadStackGuarantee सहायक हो सकता है?

आप BeginThread का उपयोग करके स्क्रैच से धागा बना सकते हैं, लेकिन यह काफी जटिल है। मेरे पास Detours का उपयोग कर एक कामकाज है। ध्यान दें कि कई Detours वेरिएंट हैं। मुझे लगता है कि केवल Cromis.Detours x64 संगत है।

unit IndividualStackSizeForThread; 

interface 

uses 
    System.Classes, 
    Cromis.Detours { http://www.cromis.net/blog/downloads/cromis-ipc/ }; 

type 
    TThreadHelper = class helper for TThread 
    constructor Create(CreateSuspended: Boolean; StackSize: LongWord); 
end; 

implementation 

var 
    TrampolineBeginThread: function(SecurityAttributes: Pointer; StackSize: LongWord; 
    ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; 
    var ThreadId: TThreadID): THandle = nil; 

threadvar 
    StackSizeOverride: LongWord; 

function InterceptBeginThread(SecurityAttributes: Pointer; StackSize: LongWord; 
    ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; 
    var ThreadId: TThreadID): THandle; 
const 
    STACK_SIZE_PARAM_IS_A_RESERVATION = $00010000; // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx 
begin 
    if StackSizeOverride <> 0 then 
    begin 
    CreationFlags := CreationFlags or STACK_SIZE_PARAM_IS_A_RESERVATION; 
    StackSize := StackSizeOverride; 
    StackSizeOverride := 0; 
    end; 

    Result := TrampolineBeginThread(SecurityAttributes, StackSize, ThreadFunc, 
    Parameter, CreationFlags, ThreadId); 
end; 

constructor TThreadHelper.Create(CreateSuspended: Boolean; StackSize: LongWord); 
begin 
    StackSizeOverride := StackSize; 
    inherited Create(CreateSuspended); 
end; 

initialization 

TrampolineBeginThread := InterceptCreate(@BeginThread, @InterceptBeginThread); 

finalization 

InterceptRemove(@TrampolineBeginThread, @InterceptBeginThread); 

end. 

मैं नहीं जानता कि क्यों Embt प्रोग्रामर ढेर आकार निर्दिष्ट करने के लिए, अगर कोई कारण जानता है, यह मेरे लिए बहुत दिलचस्प होगा की अनुमति नहीं है।

3

वहाँ बस TThread का उपयोग करके स्टैक आकार को नियंत्रित करने के लिए कोई रास्ता नहीं है। किसी भी कारण से, TThread के डिजाइनर TThread के निर्माता में एक स्टैक आकार पैरामीटर शामिल करने में विफल रहे। यह स्पष्ट रूप से एक चूक है। आपको सीधे BeginThread या CreateThread पर कॉल करना चाहिए।

यदि आप अपने हैक काम को करने के लिए बस बेताब हैं तो आपको Classes इकाई के कार्यान्वयन खंड में घोषित ThreadProc फ़ंक्शन का पता ढूंढना होगा। कुछ संभव दृष्टिकोण:

  1. जुदा TThread.Create रनटाइम पर ThreadProc का पता बाहर पढ़ने के लिए।
  2. ThreadProc के पते को ढूंढने के लिए अपने कॉल स्टैक को देखते हुए एक डमी थ्रेड बनाएं।
  3. हुक BeginThread एक चक्कर का उपयोग कर। एक डमी धागा बनाएँ। पारित थ्रेड प्रक्रिया का पता नोट करें। वह ThreadProc है।

इस प्रकार के हैकिंग के लिए विचारों का एक अच्छा स्रोत madExcept के लिए स्रोत कोड है।

हैक लागू करने का एक और तरीका फिर से BeginThread पर एक चक्कर का उपयोग करना होगा। फिर आप स्टैक आकार की आपूर्ति के लिए एक थ्रेड स्थानीय चर का उपयोग कर सकते हैं। उस थ्रेड स्थानीय चर के लिए high(LongWord) का मान "पैरामीटर के रूप में पारित मान का उपयोग करें" का अर्थ होगा, और कोई भी अन्य मान BeginThread को हटाए गए मान का उपयोग करेगा।

+0

यह 'डेल्फी डेटोरस' के साथ भी किया जा सकता है। – user3725897

+0

आप जो भी डिटोर लाइब्रेरी पसंद करते हैं उसका उपयोग कर सकते हैं –

3

David बताते हैं, आप TThread कक्षा के साथ बनाए गए धागे के लिए स्टैक आकार को नियंत्रित नहीं कर सकते हैं। आपको BeginThread या CreateThread का उपयोग करके स्वयं को वास्तविक धागा बनाना होगा।

हालांकि, अगर आप अपने आवेदन में प्रत्येक थ्रेड के लिए अलग ढेर आकार की जरूरत नहीं है, तो:
तो फिर तुम मिन ढेर आकार और अधिकतम ढेर आकार के लिए लिंकिंग विकल्पों का उपयोग कर डिफ़ॉल्ट ढेर आकार सेट कर सकते हैं।

या तो परियोजना के लिए विकल्पों में विकल्प सेट करें, या निर्देशों का उपयोग करें: {$M minstacksize,maxstacksize} {$MINSTACKSIZE number} {$MAXSTACKSIZE number}

संबंधित मुद्दे