نمایش نتایج 1 تا 20 از 20

نام تاپیک: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

  1. #1

    Question فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

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

  2. #2

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط ostovarit مشاهده تاپیک
    با سلام و تبریک سال نو در متدی از برنامه ام یک تابع را صدا زده ام که این تابع در dll ی تعریف شده است... اگر متد یک بار صدا زده شود مشکلی نیست و نرم افزار کارش را به درستی انجام میدهد... اما وقتی همزمان متد را صدا می زنیم (یعنی قبل از پایان عملیات، بار دیگر صدا زده شود) نرم افزار هنگ می کند و متوقف می شود.
    سلام.
    در اون متود از DLL چه کاری انجام میدید؟ آیا مطمئن هستید که در فراخوانی دوم این حالت پیش میاد؟ آیا این امکان وجود داره که متود مزبور پشت سر هم Call بشه به نحوی که خطاهایی مانند Stack Overflow و ... پیش بیاد؟ منظورتون از "همزمان صدا زدن تابع"، فراخوانی اون تابع از Threadهای مختلف یک Process هستش، یا فراخوانی تابع، از دو Process مجزا؟ لطفا قدری در مورد کاری که انجام داده اید توضیح بدید تا صورت مساله روشن بشه.

    موفق باشید.

  3. #3

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط mehdi.mousavi مشاهده تاپیک
    سلام.
    در اون متود از DLL چه کاری انجام میدید؟ آیا مطمئن هستید که در فراخوانی دوم این حالت پیش میاد؟ آیا این امکان وجود داره که متود مزبور پشت سر هم Call بشه به نحوی که خطاهایی مانند Stack Overflow و ... پیش بیاد؟ منظورتون از "همزمان صدا زدن تابع"، فراخوانی اون تابع از Threadهای مختلف یک Process هستش، یا فراخوانی تابع، از دو Process مجزا؟ لطفا قدری در مورد کاری که انجام داده اید توضیح بدید تا صورت مساله روشن بشه.

    موفق باشید.
    ممنون از توجهت ...

    dll وظیفه ریختن یک اپلت جاوا روی کارت (اعتباری) رو داره .... که اگر برای یک کارت فراخونی بشه (یعنی متد داخل آن یک بار صدا زده بشه) مشکلی پیش نمیاد و به درستی کار می کنه...اما زمانی که دو تا کارت داخل دستگاه داشته باشیم و متد دو بار صدا زده بشه ارور میده ... بار ها چک کردم و از این بابت که با اجرای بیش از یک بار ارور داریم مطمئنم.
    dll را به یک برنامه (فایل exe ) می دهم و برنامه با توجه به تعداد کارت ها متد داخل آن را صدا می زند...متد فقط به تعداد کارتها صدا زده میشه (یعنی همون دوبار)... این موضوع رو هم چک کردم.
    من از Threadها استفاده نکردم ... فکر می کنم مشکل زمانی پیش میاد که متد داخل dll را صدا کرده و مقداری را به آن پاس می دهم و قبل از پایان کار، متد برای کارت دوم دوباره فراخوانی شده و مقدار دیگری به آن داده میشود...و مقدار دوم جای مقدار اول نشسته و در روند کار اختلال ایجاد می کند ... زیرا گاهی اوقات وقتی برای بار دوم (برای کارت دوم) متد را فراخوانی میکنیم کارت اول را نیمه کاره رها کرده و عملیات را روی کارت دوم به طور کامل پیاده می کند.

    من به دنبال راهی هستم که متد مذکور بتواند همزمان پروسه مربوطه را برای چند کارت پیاده سازی کند... بدون آنکه اختلالی در هر پروسه ایجاد شود

    باز هم اگر نکته ای لازم بگم بفرمایید.
    آخرین ویرایش به وسیله ostovarit : یک شنبه 07 فروردین 1390 در 09:53 صبح

  4. #4

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط ostovarit مشاهده تاپیک
    من از Threadها استفاده نکردم ... فکر می کنم مشکل زمانی پیش میاد که متد داخل dll را صدا کرده و مقداری را به آن پاس می دهم و قبل از پایان کار، متد برای کارت دوم دوباره فراخوانی شده و مقدار دیگری به آن داده میشود...و مقدار دوم جای مقدار اول نشسته و در روند کار اختلال ایجاد می کند ...
    سلام.
    دو پرسش دیگه:

    1. شما چطوری از Thread ها استفاده نکرده اید، اما از درون exe می تونید قبل از اتمام کار اون متود، یک بار دیگه همون متود رو Call کنید؟ آیا در درون Process مزبور از Thread ها استفاده شده؟ یا از Timer؟
    2. آیا این Device توانایی Handle کردن چند درخواست رو بطور همزمان داره یا باید درخواستها رو سریال کنید و به Device مربوطه بدید؟

    موفق باشید.

  5. #5

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط mehdi.mousavi مشاهده تاپیک
    سلام.
    دو پرسش دیگه:


    1. شما چطوری از Thread ها استفاده نکرده اید، اما از درون exe می تونید قبل از اتمام کار اون متود، یک بار دیگه همون متود رو Call کنید؟ آیا در درون Process مزبور از Thread ها استفاده شده؟ یا از Timer؟
    2. آیا این Device توانایی Handle کردن چند درخواست رو بطور همزمان داره یا باید درخواستها رو سریال کنید و به Device مربوطه بدید؟


    موفق باشید.
    با تشکر مجدد ....
    فایل exe برای کنترل دستگاه (پرینتر مربوط به کارت) است و Thread های بیشماری را همزمان اجرا می کنه... اما در مورد صدا کردن متد چون سورس فایل exe رو ندارم نمی تونم دقیق بگم ولی یا صرفا متد را call می کند و یا برای هر بار صدا زدن آن یک Thread جدید ایجاد می کند ولی مطمئنم تایمری در کار نیست چون زمان صدا زدن متد برای هر کارت نا مشخص هست و برابر نیست...
    دستگاه توانایی اجرای چند فرمان همزمان را دارد ...
    قبلا برای حل این مشکل پروسه مربوطه را داخل فایل exe ی گذاشته بودند و ازفایل exe پنج Copy ایجاد کرده بودند و برای کارت یک exe1 برای کارت دو exe2 و... را توسط یک dll که به نرم افزار اصلی لینک می شد فراخوانی می کردند ... و exe ها به طور همزمان و مستقل از هم کارت ها را پر می کردند...
    حالا به جای 5 فایل exe یک dll ایجاد کرده ام و پروسه داخل فایل exe را در dll پیاده سازی کردم ... حالا dll را به نرم افزار اصلی لینک می کنیم ...اگر یک کارت در دستگاه باشد بدون مشکل کار انجام می شود .. اما بیش از یک کارت باعث اختلال شده و یا هیچکدام و یا یک کارت را پر می کند.
    اگر بخواهم هر بار که متد صدا زده می شود در dll ترد جدید ایجاد کنم و پروسه را داخل آن انجام دهم چه طور این کار را بکنم؟
    آیا با استفاده از ترد ها (با توجه به اینکه دستگاه حد اکثر پنج کارت میگیرد در نتیجه میتواند نهایتا پنج ترد بسازد) امکان تداخل پروسه ها وجود دارد؟ یا هر ترد جداگانه پروسه و متغییر های مقداردهی شده داخل آن را جلو میبرد؟

  6. #6

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    سلام به اقای موسوی و دیگر دوستان
    موفق شدم با تعریف Thread مشکلم رو حل کنم ........
    الان هم زمان متد رو برای هر تعداد کارت که بخوام صدا میزنم ....

    برای دوستانی که آموزش Thread رو در C++‎ میخوان پیشنهاد می کنم این لینک رو مطالعه کنند:
    http://www.codeproject.com/KB/threads/Threads_1.aspx

    کدی که من نوشتم اینه :

    char CurrentPath[_MAX_PATH];
    GetCurrentPath(CurrentPath);

    // read input from script file
    FILE *fd = NULL;
    CString ScriptFile;
    ScriptFile.Append(CurrentPath);
    ScriptFile.Append("\\install.txt");
    fd = fopen (ScriptFile, "r+");

    FILE *fd2 = NULL;
    CString ScriptFile2;
    ScriptFile2.Append(CurrentPath);
    ScriptFile2.Append("\\install2.txt");
    fd2 = fopen (ScriptFile2, "r+");

    // error
    if (fd == NULL)
    {
    ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Info", MB_OK | MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );
    LogTxt("ERROR: Could not open scriptfile.");
    ret = -1;
    goto end;
    }

    // error
    if (fd2 == NULL)
    {
    ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Info", MB_OK | MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );
    LogTxt("ERROR: Could not open scriptfile.");
    ret = -1;
    goto end;
    }

    //Load Dll
    CString PathDll;
    PathDll.Append(CurrentPath);
    PathDll.Append("\\GDll.dll");
    HINSTANCE gpsh = LoadLibrary(PathDll);
    if(gpsh == NULL)
    {
    ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Info", MB_OK | MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );
    LogTxt("ERROR: Unable to load library! (gpsh == NULL)");
    ret = -1;
    goto end;
    }

    //Load function
    handleCommands=(cfunc)GetProcAddress((HMODULE)gpsh , "handleCommands");
    if((handleCommands==NULL))
    {
    ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Info", MB_OK | MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );
    LogTxt("Unable to load function.");
    FreeLibrary((HMODULE)gpsh);
    ret = -1;
    goto end;
    }
    else
    {
    //Create Handle of Thread
    HANDLE Handle_Of_Thread_1 = 0;
    HANDLE Handle_Of_Thread_2 = 0;
    // Aray to store thread handles
    HANDLE Array_Of_Thread_Handles[3];


    //convert int to string [buf] and show reader ID
    int readerid= d->readerID();
    char buf[5];
    itoa(readerid, buf, 10);
    //MessageBox( NULL, buf, "reader id", MB_OK | MB_ICONINFORMATION );

    //Call the Function
    if(readerid == 2)
    {
    Handle_Of_Thread_1 = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)handleCommands, fd, 0, NULL);
    //ret = handleCommands(fd2,readerid);
    }
    else
    {
    Handle_Of_Thread_2 = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)handleCommands, fd2, 0, NULL);
    //ret = handleCommands(fd,readerid);
    }

    Array_Of_Thread_Handles[0] = Handle_Of_Thread_1;
    Array_Of_Thread_Handles[1] = Handle_Of_Thread_2;

    // Wait until all threads have terminated.
    WaitForMultipleObjects(2,Array_Of_Thread_Handles, TRUE, INFINITE);

    // Close all thread handles upon completion.
    CloseHandle(Handle_Of_Thread_1);
    CloseHandle(Handle_Of_Thread_2);


    در کد بالا ابتدا dll رو لود کردم و متد مورد نظر رو معرفی کردم ... سپس به قسمت تردها میرسیم که با کامنتهایی توضیح دادم.

  7. #7

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    1-لطفا متد WaitForMultipleObjects توضیح دهید ؟
    طبق چیزی که خودم خوندم این متد تا پایان کار ترد ها منتظر میمونه ... اما در متد من هنوز کار ترد ها تموم نشده ادامه کد اجرا میشه ...

    2-من میخوام ابتدا تردهای ایجاد شده پروسه رو کامل کنن بعد متدی که ترد ها در اون تعریف شدن مقداری رو return کنه؟

    3- چطور می تونم مقدار Return شده توسط متد اجرا شده داخل ترد رو بدست بیارم ... یعنی در کد زیر:

    Handle_Of_Thread_2 = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)handleCommands, fd2, 0, NULL);

    مقدار int ی رو که متد handleCommands بر میگردونه بگیرم؟

    با تشکر

  8. #8

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    سلام.
    کدی که نوشته اید چند ایراد عمده داره که در اولین فرصت به اونها اشاره خواهم کرد... (فعلا پاسخ به سوالات پست اخیر شما رو میدم).

    1. WaitForMultipleObjects باعث میشه تا Thread فعلی تا Signal شدن کلیه Handle هایی که بهش داده اید، بخوابه. به بیان دیگه، تا وقتی Object های تعیین شده به وضعیت Signaled نرفته اند، اجرای تابع مزبور ادامه پیدا خواهد کرد.
    2. برای اینکار، کافیه تا Handle به Thread های خودتون رو بصورت Array به متود WaitForMultipleObjects بدید. هر وقت کار کلیه Thread ها پایان پذیرفت، متود مزبور کارش پایان میگیره.
    3. برای گرفتن Exit Code یک Thread، می تونید از GetExitCodeThread استفاده کنید.

    موفق باشید.

  9. #9

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط mehdi.mousavi مشاهده تاپیک
    سلام.
    کدی که نوشته اید چند ایراد عمده داره که در اولین فرصت به اونها اشاره خواهم کرد... (فعلا پاسخ به سوالات پست اخیر شما رو میدم).


    1. WaitForMultipleObjects باعث میشه تا Thread فعلی تا Signal شدن کلیه Handle هایی که بهش داده اید، بخوابه. به بیان دیگه، تا وقتی Object های تعیین شده به وضعیت Signaled نرفته اند، اجرای تابع مزبور ادامه پیدا خواهد کرد.
    2. برای اینکار، کافیه تا Handle به Thread های خودتون رو بصورت Array به متود WaitForMultipleObjects بدید. هر وقت کار کلیه Thread ها پایان پذیرفت، متود مزبور کارش پایان میگیره.
    3. برای گرفتن Exit Code یک Thread، می تونید از GetExitCodeThread استفاده کنید.


    موفق باشید.
    ممنون از پاسخ هایی که دادید ...

    توضیحات تکمیلی:
    اطلاعاتی که الان مینویسم رو در ادامه کار متوجه شدم ... همون طوری که از کد پست های قبل مشخصه من ابتدا یک dll رو لود می کنم سپس متد داخل اون رو در ترد هایی صدا می زنم ...
    به این دلیل از تردها استفاده کردم که هر پروسه به صورت مجزا پیش بره اما ارور هایی که قبل از استفاده از تردها دریافت می کردم مثل invalid handle و the pipe has been ended همچنان رخ میدهد.

    استفاده از ترد ها مشکلی رو حل نکرد (البته فایدش این بودکه تا حدی با تردها در C++‎ اشنا شدم) ...

    در dll متغییری هایی به صورت Global تعریف شده اند ... آیا استفاده از چنین متغییرهایی مشکل ایجاد میکند؟ (متغییر ها رو در زیر مینویسم)


    /* Global Variables */
    static OPGP_CARD_CONTEXT cardContext;
    static OPGP_CARD_INFO cardInfo;
    static OP201_SECURITY_INFO securityInfo201;
    static GP211_SECURITY_INFO securityInfo211;
    static int gemXpressoPro = 0;
    static int platform_mode = OP_201;
    static int timer = 0;
    static BYTE selectedAID[AIDLEN+1];
    static DWORD selectedAIDLength = 0;


    برای معرفی متد داخل dll ابتدا از کد زیر استفاده کردم و سپس کتابخانه و متد آن را لود کردم :


    typedef int (WINAPI*cfunc)(FILE *);
    cfunc handleCommands;
    .
    .
    .
    //Load Dll
    CString PathDll;
    PathDll.Append(CurrentPath);
    PathDll.Append("\\GDll.dll");
    HINSTANCE gpsh = LoadLibrary(PathDll);
    if(gpsh == NULL)
    {
    ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Info", MB_OK | MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );
    LogTxt("ERROR: Unable to load library! (gpsh == NULL)");
    ret = -1;
    goto end;
    }

    //Load function
    handleCommands=(cfunc)GetProcAddress((HMODULE)gpsh , "handleCommands");
    if((handleCommands==NULL))
    {
    ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Info", MB_OK | MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );
    LogTxt("Unable to load function.");
    FreeLibrary((HMODULE)gpsh);
    ret = -1;
    goto end;
    }



    نکته:
    نکته جالبی که بهش برخوردم اینه که در شرایطی که در بین کدهای متد تعریف شده در dll (مثلا در زمان اتصال به کارت) از مسیج باکسی استفاده کنم و وقفه ای بین اتصال به کارت اول و دوم ایجاد کنم ارور های ذکر شده رفع می شوند.! سعی کردم با استفاده از متد Sleep این وقفه را ایجاد کنم وقفه ایجاد میشد اما ارور رخ می داد. فقط با وجود مسیج باکس ها کارت ها را پر می کند!

    جهت ارائه اطلاعات بیشتر فایل dll رو اینجا اتچ میکنم البته 1700 خط هست! و یک توضیح کلی بخوام دربارش بدم اینه که این dll وظیفه داره یک فایل اسکریپت رو خط بخط بخونه تنظیماتی که در فایل هست رو روی کارت اعمال کنه و فایل اپلت جاوایی که ادرسش در اسکریپت هست رو روی کارت نصب کنه .... بیشتر برای من این مهمه راهی برای مجزا کردن پروسه و مقدار دهی متغییر های آن به طور همزمان پیدا کنم ... اسم متد اصلی که از dll صدا زده میشه handleCommands هست... یک نمونه فایل Script که توسط dll تحلیل میشه هم اتچ کردم.

    با کد دارم کلنجار میرم ... امیدوارم با اطلاعاتی که دادم بتونید کمکی بهم بکنید و مشکل رو پیدا کنم ... منتظرم مشکلات و ایراد هایی که در کد دیدید رو بشنوم ....
    ممنون
    آخرین ویرایش به وسیله ostovarit : شنبه 31 اردیبهشت 1390 در 09:24 صبح

  10. #10

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    تغییرات جدیدی که اعمال کردم استفاده از MUTEX بود با این فکر که از تداخل Thread ها جلوگیری می کنه اما باعث شد که ترد ها پشت سر هم اجرا بشن یعنی بعد از اتمام ترد اول ( کارت اول) سپس ترد دوم ( کارت دوم ) فراخوانی و انجام می شد.
    و چون با هم انجام نمیشن تداخلی هم نبود دیگه! ولی من میخوام همزمان انجام بشن و مشکلی پیش نیاد ................ لطفا راه حل بدید؟
    آخرین ویرایش به وسیله ostovarit : یک شنبه 21 فروردین 1390 در 08:46 صبح

  11. #11

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    فعلا برای اینکه به بقیه پروژه برسم به تعداد دفعاتی که میتونه متد صدا زده بشه ( 5 بار) dll ایجاد کردم (کپی پیست با نام های مختلف)و در هر بار صدا زدن یک dll رو فراخونی کردم در نتیجه تداخلی نداریم ولی هنوز دنبال راهی هستم که یک dll داشته باشیم و بتونیم به تعداد مورد نیاز همزمان فراخونیش کنیم و تداخلی هم پیش نیاد ...

  12. #12

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    درباره ی این موضوع مجدد تحقیق کردم و به این لینک برخوردم :
    http://support.microsoft.com/kb/106553

    در لینک بالا اشاره شده به مقدار handle که به متد LibMain پاس داده می شود... ودر توضیح هندل گفته که handle to instance of dll اما dll من متد اصلی نداره و من برای صدا زدنش هندلی رو پاس نمیدم ... من بعد از لود dll به متد داخل آن اشاره دارم همین! نظرتون در این مورد چیه؟

    بعد درباره WEP گفته که من این کلمه رو اخر DEF اضافه کردم نشناختش و به دردم نخورد...

    من فکر میکنم مشکلم تو مورد پایین باشه که توضیح داده:
    Be Careful When Storing Data in Static Variables

    If you try to store data in a DLL using global or static variables, don't be surprised if these values have changed when you next call your DLL. The data stored in this way will be common to all applications that access this DLL. No matter how many applications use a DLL, there is only one instance of the DLL. The best way to get around this is to return structures from the DLL and pass them in again when they are needed.


    اما راه حلش رو نفهمیدم...

    هیف که حجم پروژم بالاست (240 مگه) وگرنه آپ می کردم ...

  13. #13
    کاربر دائمی آواتار FastCode
    تاریخ عضویت
    تیر 1388
    محل زندگی
    /dev/null
    پست
    3,486

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    خیلی جالبه.
    برای همین ما توی لینوکس fork داریم.

    توی ویندوز فکر میکنم مشکل شما با __declspec(thread) برطرف میشه

  14. #14

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط FastCode مشاهده تاپیک
    خیلی جالبه.
    برای همین ما توی لینوکس fork داریم.

    توی ویندوز فکر میکنم مشکل شما با __declspec(thread) برطرف میشه
    ممنون از پاسخ

    من اینو __declspec(thread) یک بار برای معرفی متغییرهایی که متد میگیره استفاده کردم فرقی نکرد یک بار متغییر های داخل متد رو با این تعریف کردم کلا ارور میده موقع اجرا ... نمیدونم کجا میشه ازش استفاده کرد که نتیجه ای هم بده؟؟!!

    به نظرتون میشه هر بار برای لود dll یک ترد ساخت ... توفیقی میکنه؟؟؟

  15. #15

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    سلام.
    اجازه بدید به کدی که قبلا ارسال کرده بودید برگردیم.

    در dll متغییری هایی به صورت Global تعریف شده اند ... آیا استفاده از چنین متغییرهایی مشکل ایجاد میکند؟
    پاسخ این سوال، بستگی به این داره که وقتی تابعی از DLL رو در Context یک Thread فراخوانی می کنید، چطوری با اون متغیر کار کنید. اگر قرار باشه یک Thread متغیر static شما رو تغییر بده و در آن واحد، Thread دیگه ای اون مقدار رو بخونه، بله. Race Condition میتونه پیش میاد و برنامه میتونه به شرایط اط قبل تعریف نشده بره. برای همین هستش که شما باید دسترسی به اون متغیرها رو Thread-Safe کنید.

    فرمودید از Mutex استفاده کردید، اما Call ها Serial شدند. خوب، طبیعیه. اینجا شما نباید از Mutex استفاده کنید... کافیه تا یک یا چند Critical Section (ناحیه بحرانی) در کد تعریف کنید. سپس دسترسی به این متغیرهای static رو در این نواحی بحرانی برنامه ریزی کنید. به این ترتیب، وقتی Thread ای وارد اون ناحی بحرانی میشه، دیگر Thread ها منتظر میمونن تا Thread ای که (اصطلاحا) Lock رو گرفته کارش تموم بشه و از ناحیه بحرانی خارج بشه. وقتی Thread از اون ناحیه خارج شد، Thread دیگه میتونه وارد اون ناحیه بشه.

    حقه اصلی در پیاده سازی و استفاده از Critical Section این هستش که ناحیه بحرانی رو حتی الامکان کوچک نگه دارید. یعنی کدی که در این ناحیه اتنجام میشه باید سریع السیر اجرا یشه و اون ناحیه رو ترک کنه تا Thread های دیگه ای که برای اجرا Schedule شده اند، بتونن وارد اون ناحیه بشن.

    برای استفاده از Critical Section ها، در MSDN برای CCriticalSection و CSingleLock جستجو کنید. (حتما از CSingleLock استفاده کنید که کار Unlock کردن توسط خود کلاس کنترل بشه، و الا ممکنه کد شما بیش از این Error-Prone بشه). اگر هم از MFC استفاده نمی کنید، می تونید از EnterCriticalSection و LeaveCriticalSection استفاده کنید. بدین ترتیب، میتونید دسترسی به Object های مورد نظر رو Thread-Safe کنید...

    موفق باشید.

    پاورقی: من هنوز فرصت نکردم کد شما رو بگیرم و بررسی کنم. خدا بخواد این هفته اینکارو می کنم که از شرمندگی شما هم در بیام.

  16. #16

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    مواردی رو که فرمودید چک می کنم و جستجویی روش انجام میدم نتایجش رو باز میگم انشالله که بتونم از پسش بر بیام ....

    نقل قول نوشته شده توسط mehdi.mousavi مشاهده تاپیک
    پاورقی: من هنوز فرصت نکردم کد شما رو بگیرم و بررسی کنم. خدا بخواد این هفته اینکارو می کنم که از شرمندگی شما هم در بیام.
    فایلی که اپلود کردم شامل کل کدهای من در dll میشه که یک متد اصلی به نام handleCommands داره ...
    از اینکه وقتتون رو میزارید و به فکر هستید تا مشکل منو حل کنید ممنونم ...

  17. #17
    کاربر دائمی آواتار FastCode
    تاریخ عضویت
    تیر 1388
    محل زندگی
    /dev/null
    پست
    3,486

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط ostovarit مشاهده تاپیک
    ممنون از پاسخ

    من اینو __declspec(thread) یک بار برای معرفی متغییرهایی که متد میگیره استفاده کردم فرقی نکرد یک بار متغییر های داخل متد رو با این تعریف کردم کلا ارور میده موقع اجرا ... نمیدونم کجا میشه ازش استفاده کرد که نتیجه ای هم بده؟؟!!

    به نظرتون میشه هر بار برای لود dll یک ترد ساخت ... توفیقی میکنه؟؟؟
    مطمئنید که فرقی نکرد؟تست کردید؟
    محل استفادش باید جاهایی باشه که ترد ها متغیر های global رو میخونند.
    راستش نمیدونم.هنوز این کار رو نکردم.ولی در یک فایل __declspec(thread) جواب میده.

    یک راه دیگه.(Hacky)
    سعی کردید در runtime فایل رو به تعداد مورد نیاز کپی کنید و از LoadLibrary استفاده کنید؟

  18. #18

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط FastCode مشاهده تاپیک
    مطمئنید که فرقی نکرد؟تست کردید؟
    محل استفادش باید جاهایی باشه که ترد ها متغیر های global رو میخونند.
    راستش نمیدونم.هنوز این کار رو نکردم.ولی در یک فایل __declspec(thread) جواب میده.

    یک راه دیگه.(Hacky)
    سعی کردید در runtime فایل رو به تعداد مورد نیاز کپی کنید و از LoadLibrary استفاده کنید؟
    تست کردم جواب نداد... در حال حاضر پنج تا کپی ازش گذاشتم ... همین روشی که شما میگی و مشکلی نداره ... ولی میخوام به جای پنج تا یک فایل dll باشه ... ممنون

  19. #19

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    نقل قول نوشته شده توسط FastCode مشاهده تاپیک
    یک راه دیگه.(Hacky)
    سعی کردید در runtime فایل رو به تعداد مورد نیاز کپی کنید و از LoadLibrary استفاده کنید؟
    لطفا درباره این Hacky یک توضیحی بدید ... نمونه کدی هم باشه خوبه ... چون سرچ کردم چیز به دردبخوری نبود ...


    با Boost.Thread کار کردید ؟؟؟ ایا به درد کار من میخوره ؟
    توضیحش :
    enables the use of multiple threads of execution with shared data in portable C++‎ code
    http://www.boost.org/doc/libs/1_46_1...ted/index.html
    آخرین ویرایش به وسیله ostovarit : دوشنبه 19 اردیبهشت 1390 در 10:09 صبح

  20. #20
    کاربر دائمی آواتار FastCode
    تاریخ عضویت
    تیر 1388
    محل زندگی
    /dev/null
    پست
    3,486

    نقل قول: فراخوانی مجدد یک متد قبل از پایان فراخوانی های پیشین

    Hacky Code یعنی کد .....

    فرقی با ترد معمولی نداره.
    راه اصولی و ساده ای که به نظر من میرسه اینه که متغیر های global رو به عنوان parameter درون کد پاس بدید.

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •