PDA

View Full Version : thread



benyamin_pc
چهارشنبه 30 آبان 1386, 10:39 صبح
با زبان سی یا سی پلاس پلاس تحت داس یعنی نسخه 3
اگر بخواهیم دو تابع را موازی اجرا کنیم یعنی کامپیوتر برای اتمام یک تابع صبر نکند و سپس تابع دیگر را اجرا کند چه باید بکنیم؟

Nima_NF
چهارشنبه 30 آبان 1386, 18:54 عصر
داس یک سیستم عامل قدیمی می باشد که از ضعف های آن عدم امکان موازی سازی ها و اجرای همزمان چند پروسه بود. شما در داس اصلا thread ندارید.
اگر منظور شما از داس همان برنامه نویسی کنسول ( صفحه سیاه رنگ) هست آنگاه قضیه فرق می کند و این امکان وجود دارد ولی با شرایط زیر:
- استفاده از یک کامپایلر جدیدتر تحت ویندوز مثل ++visual C به جای turboC و به همان شکل برنامه نویسی کنسول کنید و سپس به راحتی برای استفاده از thread از توابع 32/64bit ویندوز با نوشتن هدر فایل آنها در بالای کدهای خود از آن ها استفاده کنید.
ضمنا شما می توانید از توابع خود ++C/C برای پروسه ها هم استفاده کنید که بین سیستم عامل ها مشترکند مثل دستور زیر:




<process.h>

_beginthread( );
_endthread( );

sasan_vm
چهارشنبه 30 آبان 1386, 19:31 عصر
با برنامه نویسی TSR برای dos می توانید این کار را شبیه سازی کنید. روش کار به این صورت است که باید interupt ها را دستکاری کنید و در انتها برنامه را در خافظه مقیم کنید.
برای نمونه یک ساعت که در زمان دانشجویی نوشتم ارسال میکنم:



// FILE: CLOCK.CPP Show time on screen, TSR program.
// BY: M.Tanhaey February 1997

#include <dos.h>
#include <stdlib.h>
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
#define ATTR 0x3000 // (black on cyan)
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@
extern unsigned _heaplen=512;
extern unsigned _stklen=206;
char Stack[0x200];
int Count=0, ss, sp;
unsigned (far * Screen)[25][80];
char Hour1, Hour2, Min1, Min2, Sec1, Sec2;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@
void Bell(void);
void Print(char *);
int Find_psp(void);
void Uninstall(void);
void interrupt ( *OldTimer ) (__CPPARGS);
void interrupt NewTimer (__CPPARGS);
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@
void Bell(void)
{
sound(500);
delay(200);
nosound();
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@
void Print(char *Text)
{
union REGS r;
r.h.ah=9;
r.x.dx=(unsigned) Text;
intdos(&r,&r);
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@
int Find_psp(void)
{
unsigned i = _psp;
char flag=0;
while ( i )
{
i--;
if ( peekb(i,0)=='M' && peek(i,8)==peek(_psp-1,8)
&& peek(i,10)==peek(_psp-1,10) )
{
if ( flag )
{
_psp=peek(i,1); return 1;
}
else flag=1;
}
}
return 0;
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@
void Uninstall(void)
{
poke(0, 0x70, peek(_psp, 0x80)); // restore offset 1ch
poke(0, 0x72, peek(_psp, 0x82)); // restore segment 1ch
freemem(peek(_psp,0x2c));
freemem(_psp);
Print("\n\r CLOCK Uninstalling finished.\n\r$");
exit(0);
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@
void interrupt NewTimer(__CPPARGS)
{
static unsigned Regulator=0;
OldTimer();
disable();
ss=_SS;
sp=_SP;
_SS=_DS;
_SP=(unsigned)&Stack[0x200];
enable();
Regulator++;
if ( Regulator!=90 && Regulator!=89 ) Count++;
else { Regulator=0; goto wer; }
if ( Count==18 ) { Count=0; Sec2++; }
if ( Sec2==58 ) { Sec2=48; Sec1++; }
if ( Sec1==54 ) { Sec1=48; Min2++; }
if ( Min2==58 ) { Min2=48; Min1++; }
if ( Min1==54 ) { Min1=48; Hour2++; Bell(); }
if ( Hour2==58 ) { Hour2=48; Hour1++; }
if ( Hour1==50 && Hour2==52 ) { Hour1=Hour2=48; }
wer:
(*Screen) [0][70] = ' ' + ATTR;
(*Screen) [0][71] = Hour1 + ATTR;
(*Screen) [0][72] = Hour2 + ATTR;
(*Screen) [0][73] = ':' + ATTR;
(*Screen) [0][74] = Min1 + ATTR;
(*Screen) [0][75] = Min2 + ATTR;
(*Screen) [0][76] = ':' + ATTR;
(*Screen) [0][78] = Sec2 + ATTR;
(*Screen) [0][77] = Sec1 + ATTR;
(*Screen) [0][79] = ' ' + ATTR;
disable();
_SS=ss;
_SP=sp;
enable();
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@
void main(void)
{
if ( Find_psp() ) Uninstall();
Print("\n\r CLOCK program install succesfuly.$");
Print("\n\r By: Mansoor Tanhaey Zahedan_IRAN , February 1997\n\r$");
poke(_psp, 0x80, peek(0,0x70)); // store offset 1ch in _psp offset 80h
poke(_psp, 0x82, peek(0,0x72)); // store segment 1ch in _psp offset 82h
OldTimer=getvect(0x1c);
Screen = (unsigned (far*) [25][80] ) MK_FP(0xb800,0);
struct time T;
gettime(&T);
Sec1 = 48 + (int) (T.ti_sec/10);
Sec2 = 48 + T.ti_sec % 10;
Min1 = 48 + (int) (T.ti_min/10);
Min2 = 48 + T.ti_min % 10;
Hour1 = 48 + (int) (T.ti_hour/10);
Hour2 = 48 + T.ti_hour % 10;
setvect(0x1c,NewTimer);
keep( 0, _SS + (_SP/16) - _psp );
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@

benyamin_pc
چهارشنبه 30 آبان 1386, 23:56 عصر
آقای نیما به درستی منظور من را متوجه نشدن
معلومه که داس چند نخی نداره اما من نگفتم با داس گفتم با سی
همون طور که ویندوز رو با سی نوشتن و چند نخی داره پس میشه برنامه ای نوشت که چند نخی رو اجرا کنه
البته برنامه ای که دوستمون گذاشتن رو باید بخونم تا ببینم همونیه که تو ذهنمه یا نه
البته دقیقا" من می خوام دو تابع که هر کدوم برای اجرا مثلا" 20 ثانیه تاخیر ایجاد می کنند رو همزمان اجرا کنم به صورتی که بعد 20 ثانیه دو تابع اجرا شن اما بجای 10% سی پی یو 20% یا بیشتر سی پی یو کار کنه
البته نه به این شکل که خطوط دو تابع رو تو یه تابع با هم ادغام کنم بلکه همچنان دو تابع مجزا بمونن!

Nima_NF
پنج شنبه 01 آذر 1386, 18:04 عصر
اما من نگفتم با داس گفتم با سی
فکر نمی کنید 2 خط سوال برای فهمیدن منظور شما کم بود ؟

می تونم سوال کنم اصلا چرا می خواهید این کار را انجام دهید ؟
پروژه دانشجویی ؟ که می تواند چیز مفید تر دیگری باشد.
پروژه عملی/تجاری ؟ که باز یک اشتباه دیگر است.

در هر صورت این کار بر می گردد به سیستم عامل ، اطلاعات پردازنده و حافظه ، پس شما خودتان باید آن را از طریق اسمبلی در لابلای کدهای C خود شبیه سازی کنید. یعنی مثلا برای تابعی با این حلقه:



for ( i=0 ; i<100 ; i++)
count++;

باید بدانید که الآن در کجای حلقه و کدام خط کد های ماشین هستید ، مقدار ECX و سایر رجیستر ها چه می باشد و سپس هر چند میلی ثانیه از آنجا خارج شوید و اطلاعات را در جایی مثل stack ذخیره کنید و سپس به مکان دیگر(تابع thread دیگر شما) پرش کنید و این کار را مدام تکرار کنید.
برای میزان در صد استفاده از پردازنده هم خودتان باید میزان اولویت را برای هر تابع thread خود شبیه سازی کنید.

Inprise
پنج شنبه 01 آذر 1386, 18:11 عصر
معلومه که داس چند نخی نداره اما من نگفتم با داس گفتم با سی
همون طور که ویندوز رو با سی نوشتن و چند نخی داره پس میشه برنامه ای نوشت که چند نخی رو اجرا کنهنه . سعی کن سوالاتت رو با فرضهای درست بپرسی یا اول ازشون مطمئن بشی . داس سیستم عاملی برای Real Mode هست و ویندوز ( های فعلی ) سیستم عاملی برای Protected Mode و مسئله ریسمان و غیر ، از وابستگی اش به تعداد پردازنده که بگذریم ، تحت تاثیر مدل مدیریت حافظه هستند ، نه خود سیستم عامل یا زبان برنامه نویسی سیستم عامل. پس جوابت بطور کل منفی هست .



البته دقیقا" من می خوام دو تابع که هر کدوم برای اجرا مثلا" 20 ثانیه تاخیر ایجاد می کنند رو همزمان اجرا کنم به صورتی که بعد 20 ثانیه دو تابع اجرا شن اما بجای 10% سی پی یو 20% یا بیشتر سی پی یو کار کنهروشهائی که بهت پیشنهاد دادن هر کدوم کمک میکنن به چیزی شبیه به این نزدیک بشی ، اما این مسئله در عمل اتفاق نمیفته . یعنی نمیتونی بهر حال دو تابع رو همزمان اجرا کنی و مدیریتی روی عملکرد پردازنده داشته باشی . این محدودیتها یکی از مهمترین دلائلی هستن که تکنولوژی جلو میره . یک کامپیوتر با دو پردازنده بخر و سیستم عاملی که کرنل SMP داشته باشه ( مثل ویندوزهای جدید یا لینوکسی با این امکان ) بعد بسادگی میتونی به چنین چیزی برسی . اگر کاری که میخواهی انجام بدی علمی یا محاسباتی نیست و در کل وابستگی حادی به زمان نداره که در کل اصلا لازم نیست نگران این حرفها باشی چون لابد بین کسری از ثانیه و چند ثانیه تفاوت زیادی اونجا وجود نداره .

benyamin_pc
پنج شنبه 01 آذر 1386, 18:38 عصر
با سلام خدمت Iprise عزیز
فکر می کنم تو توضیحاتم رسونده باشم که من چیزی به صورت real time نمی خوام که با دو سی پی یو یا بیشتر این کار رو به صورت واقعی موازی کنم بلکه همون وقفه و پرش و جابجایی سی پی یو بین پردازش های کوچیک مد نظر هست البته مشکل من هم دقیقا" شبیه سازی تابعی هست که بدون به هم زدن فرم تابع های دیگر بشه بین اون ها تو زمان های کم جابجا شد
در واقع ما دو تابع داریم که یه تابع دیگه میاد اینها رو موازی اجرا میکنه البته نه موازی به شکل واقعی!
----------
کد دوستمون فکر می کنم شبیه این کار رو کرده باشه اما کد رو درست متوجه نشدم یکم سطح بالا بود اگه یکم در موردش دوستان توضیح بدن ممنون میشم.مخصوصا" کاربرد اون اعداد هگز.
مثلا" جایی شبیه این char Stack[0x200];