PDA

View Full Version : حداكثر تعداد Thread



joker
دوشنبه 14 آذر 1390, 16:19 عصر
نياز داشتم كه براي يك اپليكشن تعداد ترد هاي زيادي را به صورت همزمان اجرا داشته باشم
ولي ظاهرا يك محدوديت ذاتي براي حداكثر2000 ترد هست ( ضمن آزاد بودن cpu و ram بعد از اين تعداد Create Thread به مشكل بر ميخوره )
من نياز به حداقل 50 هزار ترد همزمان دارم.
چه راه حلي پيشنهاد ميكنيد براي حل اين مشكل ؟

Mahmood_M
دوشنبه 14 آذر 1390, 20:00 عصر
محدودیتی برای تعداد Thread ها وجود نداره ، اما هر Thread یک Thread Stack در فضای Process ایجاد میکنه که تعداد زیاد این Thread Stack ها ، باعث پر شدن فضای حافظه ی Process میشه
لینکر در حالت پیش فرض 1 مگابایت رو برای مقدار Stack Size (http://msdn.microsoft.com/en-us/library/ms686774) توی تابع CreateThread در نظر میگیره ، با توجه به اینکه توی System های X86 ، مقدار حافظه ی مجاز برای هر Process حدود 2 GB هست ، پس Process شما فقط می تونه در حدود 2048 ترد ایجاد کنه ، راه حل برای ایجاد بیشتر Thread اینه که در تابع CreateThread مقدار StackSize رو مقداری کمتر از 1 مگابایت وارد کنید ( ولی باز هم 50.000 ترد برای سیتمهای 32 بیت زیاده ! )
در سیستمهای 64 بیت محدودیت 2 گیگابایت برای حافظه ی Process وجود نداره ( درواقع خیلی بیشتر از 2 GB هست و مشکل ساز نیست ) و می تونید حدود 50 هزار ترد ایجاد کنید ( البته بستگی به مقدار RAM سیستم داره )
در اینجا (http://blogs.technet.com/b/markrussinovich/archive/2009/07/08/3261309.aspx) یک تست جالب در این مورد انجام شده که نتایجش می تونه کمکتون کنه

موفق باشید ...

mobintmu
دوشنبه 14 آذر 1390, 21:14 عصر
واقعا علاقه مند شدم بدونم چه برنامه ای نیاز به ۵۰۰۰۰ تا نخ کشی داره ؟
احیانا پدر اون سیستم عامل در نمی اد بخواد یه همچین چیزی رو اجرا کنه
اگه هر کدومشون هم ۲ تا منبع مشترک استفاده کنن میشه ۱۰۰۰۰۰۰ تا ناحیه ی بحرانی !!!!!

joker
دوشنبه 14 آذر 1390, 23:25 عصر
ممنون
مشكلي توي سوئيچ كردم روي 64 بيتي و نوع ويندوز خاصي ندارم .

توي يك سيستم 64 بيتي 2 هسته اي هم تفاوتي حاصل نشد
البته سيستمه 2 گيگ رم داره ، ولي موردي كه بود اينه كه در حالت نرمال 2هزار ترد بود با كدي كه در ادامه مينويسم به 4هزارتا حداكثر رسيد
با توجه به موردي كه در داكيومنتها اومده بود يعني موردSTACK_SIZE_PARAM_IS_A_RESERVATION
وقتي به حداكثر تعداد قابل ساخت يعني حدود 4هزار ترد ميرسه و ديگه ادامه نداره ( يعني ساخت تردهاي بعدي با خطا مواجه ميشه ) همچنان 2سوم RAM آزاد هست.
يك جهش 2برابري باز هم به شك م انداخته ، نميدونم اين محدوديت از چه جنسيه بلاخره ...
براي ساخت اين تعداد ترد حدود 200 مگابايت از رم اشغال ميشه




unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

const
STACK_SIZE_PARAM_IS_A_RESERVATION : DWORD = $00010000;

type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
hStartEvent : THANDLE = 0;
i : integer;
thid : cardinal;

function NtCurrentTeb() : pointer; stdcall; external 'ntdll';
//function SetThreadStackGuarantee(staksize:integer):boolean stdcall; external 'kernel32.dll';


implementation

{$R *.dfm}

function ThreadProc(iThread : cardinal): DWORD; stdcall;
begin
// Form1.memo1.Lines.Add((format('Thread : %8d, Stack : %08p, TEB : %08p',
// [iThread, @iThread, NtCurrentTeb()])));
SetEvent(hStartEvent);
Sleep(INFINITE);
result := 0;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
//SetThreadStackGuarantee(1000);

hStartEvent := CreateEvent(0, FALSE, FALSE, 0);
for i := 0 to 10000 do begin
if (CreateThread(nil, 512*1024, @ThreadProc, POINTER(i), STACK_SIZE_PARAM_IS_A_RESERVATION, thid) = 0) then break;

// WaitForSingleObject(hStartEvent, INFINITE);
end;
CloseHandle(hStartEvent);

memo1.Lines.Add('press enter...');


end;

end.


اضافه شد :
با برنامه testlimit روي يك سيستم 32 بيتي تا تعداد 30 هزارترد را ساخت
و روي 64 بيتي تا72036 هزارتا
خب با توجه به اين موضوع چه الگوريتم يا توابعي براي ساخت ترد پيشنهاد ميكنيد؟