arven_andomil (09-11-09), Moein (09-11-09)
عضو VIP شهرسختافزار
علم كامپيوتر همواره المانهاي طراحي خود را از زندگي واقعي وام گرفته است و تلاش دارد خود را به زندگي واقعي نزديكتر كند. خط لوله (Pipeline) نقش مهمي را در نرمافزار بازي ميكند. بهدليل اينكه همه ما سيستم لولهكشي را ميشناسيم و با آن آشنايي داريم، مفهوم نرمافزاري آن را بهتر درك خواهيم كرد.
همانطور كه گفتيم لولهكشي در نرمافزار، كاربردهاي زيادي دارد، بهعنوان مثال از لولهكشي در مورد الگوريتمهاي طولاني علمي و رياضي كه هر مرحله بايد پشت مرحله بعدي انجام شود، خواندن و نوشتن از روي ديسك، استفاده از بافر ورودي/خروجي، و حتي پردازشهاي گرافيكي ميتوان استفاده كرد.
خط لوله، مجموعهاي از تكه لولهها است كه بهروشهاي مختلفي ميتوانند بهيكديگر متصل شوند تا يك وظيفه خاص را انجام دهند. در سادهترين شكل ممكن، يك خط لوله، يك سر و يك دم دارد كه ميتوانند يكي باشند. (هر چند اگر فقط يك لوله داشته باشيم، هدف استفاده از خط لوله را زير سوال بردهايم.)
در شماره گذشته، در مورد آمادهسازي برنامههاي شيگرا، براي كار با خط فرمان صحبت كرديم. يكي از قويترين سيستمهاي عامل دنيا (Unix)، محيط خط فرمان قوياي دارد و همه امور را بهسادگي با خط فرمان انجام ميدهد. اين سيستم عامل، كه سيستمهاي خط لوله را بهخوبي پياده كرده است، مثال خوبي است براي بهكار گيري خط لوله در خط فرمان و آماده سازي برنامهها براي كار با خط فرمان.
در يونيكس، خروجي هر دستور (دم لوله) بهعنوان ورودي براي يك دستور يا يك برنامه ديگر بهكار ميرود (سر لوله بعدي) و بههمين ترتيب ميتوان چندين دستور و يا چندين برنامه را يكجا با هم اجرا و نتيجه را بهطور واحد دريافت كرد.
اگر شماره قبلي را بهخاطر بياوريد، از كلاس خاصي بهنام فايل استفاده شد كه امور مرتبط با كپي و انتقال فايل را به آن واگذار كرديم تا براساس اصل استفاده مجدد در شيگرايي، بتوانيم درخواستهاي مختلف را با آن پاسخ بدهيم. در روش يونيكسي آن، كه در اين شماره ميخواهيم در موردش صحبت كنيم، خروجي يك دستور را به ورودي يك دستور ديگر ميدهيم. بگذاريد با يک مثال بيشتر در اين مورد بحث کنيم:
فرض کنيد که قرار است در هنگام اجراي دستور، نياز به کپيکردن فايل باشد ما ديگر به کلاسي براي کپي کردن فايل نياز نداريم بلکه دستور Copy را فراخواني ميکنيم، و متدهاي CopyFile و MoveFile که قرار بود در کلاس ثالث ديگري به اسم File بگذاريم، بهصورت خصوصي در کلاس مربوط به کلاس Copy قرار ميدهيم. به اين ترتيب کدهاي نوشته شده کم خواهد شد و ديگر براي انجام عمل کپي نياز به فراخواني متدهاي استاتيک کلاس File نداريم و فقط هر بار خواستيم که فايل را كپي يا حتي جابهجا کنيم دستور مربوط به Copy را فراخواني ميکنيم، حال کدهاي نوشته شده در مقاله هفته پيش را با استفاده از اين روش باز نويسي ميکنيم، بدين ترتيب کلاس Copy ما به شکل زير در ميآيد:
class Copy : public baseCommand{
public:
Copy(int argc, char* argv[]) : baseCommand(argc,argv){}
void execute(){
if(this-»contain("/X") || this-»contain("/x")){
this-»copyFile(this-»argv[1], this-»argv[2]);
}
else
this-»moveFile(this-»argv[1],this-»argv[2]);
}
private:
void copyFile(const char* srcFile,const char* dstFile){}
void moveFile(const char* srcFile,const char* dstFile){}
};
بسيار خوب حالا فرض ميکنيم كه به فراخواني دستوري براي کپي کردن دايرکتوري نياز داريم (اين دستور در سيستم عامل ويندوز با XCopy شناخته ميشود و در سيستم عامل لينوکس با استفاده از دستور cp انجام ميشود. براي توضيحات بيشتر اين دستور ميتوانيد به لينک زير مراجعه كنيد:
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/xcopy.mspx?mfr=true
فرض کنيد ما ميخواهيم اين دستور را در برنامه خودمان داشته باشيم، باتوجه به روش قبلي که در مقاله هفته پيش نوشته شد، بايد يك کلاس مربوط براي Directory تعريف کنيم در اين کلاس بايد متدي براي کپي کردن Directory بنويسيم و اين متد، متد File:Copy را براي همه فايلهاي درون دايرکتوري فراخواني ميکند، خوب اگر با استفاده از روش ذکر شده در اين مقاله بخواهيم همچين کاري را انجام دهيم بايد يك کلاس مربوط به دستور dir را نيز تعريف کنيم، در اين کلاس دستور dir را با فرمان /s اجرا ميکنيم و سپس خروجي را از دستور dir ميگيريم. اين خروجي شامل آدرس فايلها و زيردايرکتوريها ميشود. فايلها را با استفاده از دستور Copy در جايي که بايد کپي شوند، کپي ميکنيم و دايرکتوريها را نيز با استفاده از دستور mkdir در محل مشخص ايجاد ميکنيم و اين عمل تا زماني انجام ميشود که آدرس فايل يا دايرکتوري در خروجي دستور dir موجود است. اگر بخواهيم مطالب گفته شده را بصورت شبه کد بنويسيم به اين صورت خواهد بود:
اينجا ما در کلاس xCopy يک شي از کلاس Copy ساختهايم و آنرا اجرا کرديم خوب بگذاريد کد را کمي زيباتر کنيم که بحث لولهكشي را هم بهصورت کامل در آن پياده كرده باشيم. بهجاي استفاده از کلاس Copy ميتوانيم از کلاس Helper که در مقاله هفته پيش توضيح داده بوديم، استفاده کنيم. همچنين بهجاي ساخت شي از روي کلاس Copy، ميتوانيم بدون ايجاد شي و با اجراي خود برنامه، دستور كپي را اجرا كنيم. بهعبارت ديگر دقيقا دستور را اجرا کرديم و به برنامه خود اعلام کردهايم که دستور کپي را اجرا کن، نهاينكه متد execute کلاس Copy را اجرا كنيم.
بحثي كه ارائه كرديم، فقط گوشهاي از مفهوم خطلوله بود. بياييد يكي از كاربردهاي اصلي خط لوله را (كه در لينوكس و يونيكس استفاده ميشود) با هم بررسي كنيم:
در خط فرمان لينوكس، كاراكتر پايپ (|) براي استفاده چند دستور پشت هم بهكار ميرود. بهعنوان مثال، خط دستور زير را در نظر بگيريد:
$ ps -ax | grep click
اين دستور ابتدا دستور ps را اجرا ميكند، و بعد خروجي خود را به grep ميدهد تا تنها ركوردهايي را برگرداند كه عبارت كليك داخل آنها وجود دارد.
class xCopy : public baseCommand{
public:
void execute(){
dir _dir;
_dir.execute();
int index = 0;
for(index ; index « _dir.fileCount ; index++){
copy.execute();
}
}
}
شادي اسدي
jamejamonline.ir
arven_andomil (09-11-09), Moein (09-11-09)
|
|
1 کاربر در حال مشاهده این موضوع. (0 عضو و 1 میهمان)
Bookmarks