PDA

View Full Version : طرح یه سوال در مورد CWinThread ؟؟؟



Moharram
چهارشنبه 28 فروردین 1387, 12:44 عصر
سناریو:
داخل حلقه بینهایت یک Thread از نوع CWinThread، سه متغیر دارم و موقع Suspend شدن Threadها این سه رو میخونم.
در اولین TRACE بعد از Resume شدن فقط دو تا از متغیرها Update میشن.
تفسیر من اینه که از وسط حلقه Suspend شده و بعد از Resume شدن از همون وسط کار رو ادامه داده)..... !!!

سوالات:
1- وقتی یک Thread رو Suspend میکنیم از کجای Loop مییاد بیرون؟

2- موقع Suspend کردن با دستور m_pThread->SuspendThread قطعا همون لحظه Suspend نمیشه. آیا میشه یه طوری با یه فلگی فهمید که Thread کِی موفق میشه Suspend بشه، تا ما در همون لحظه بتونیم متغیرهامونو Update کنیم؟

3- چطوری میشه CWinThread ها رو Terminate کرد؟

با تشکر

Nima_NF
چهارشنبه 28 فروردین 1387, 17:36 عصر
1) به این سوال نمی توان جواب قطعی داد، توجه داشته باشید که تمامی اطلاعات در یک پشته ذخیره می شود که با توجه به آن داده ها می تواند دوباره از همان قسمت کار خود را ادامه دهد (که می تواند هر کجای حلقه باشد)

2) اصلا شما نباید از SuspendThread و ResumeThread برای توقف thread استفاده کنید مگر اینکه برنامه شما یک debugger می باشد.
پس اگر می خواهید این کار را انجام دهید باید از طریق سایر موارد همزمان سازی ها ( مثل Event و wait) این کار را انجام دهید و هرگاه که می خواهید thread شما به حالت تعلیق برود از طریق ارسال پیام یا سیگنالی خود thread این کار را انجام دهد.(یعنی در بهترین مکانی که خودتان در نظر دارید)

3) از داخل thread کد AfxEndThread را فراخوانی کنید.

Moharram
چهارشنبه 28 فروردین 1387, 19:02 عصر
3) از داخل thread کد AfxEndThread را فراخوانی کنید.

اینکه Thread باید خودش، خودش رو End کنه یعنی چی ؟
مگه نباید از بیرون از Thread برای توقف Thread تصمیم گیری کرد؟

در ضمن اگه لطف کنید و یه Sample بذارید خیلی ممنون میشم ...

با تشکر

Nima_NF
چهارشنبه 28 فروردین 1387, 22:05 عصر
اینکه Thread باید خودش، خودش رو End کنه یعنی چی ؟
مگه نباید از بیرون از Thread برای توقف Thread تصمیم گیری کرد؟

شما می توانید thread را از خارج از آن توسط تابع win32 API با نام TerminateThread به پایان برسانید اما این کار بسیار خطرناک می باشد و عواقب غیر منتظره ای خواهد داشت.

لذا باید به طریقی از توابع امن تر مانند AfxEndThread این کار را انجام دهید، یعنی شما باید روشی ایجاد کنید که با ارسال پیامی به thread بگویید که باید خود را ببندد. (حال یا از طریق متغیر ها یا روش های همزمان سازی)

در مثال زیر thread در قسمت WaitForSingleObject در حالت تعلیق خواهد ماند تا سیگنالی به آن ارسال شود (از طریق Event) و سپس برنامه بسته می شود(البته توجه داشته باشید که در این برنامه m_bAutoDelete به false تغییر داده شده است تا برنامه خودش به پایان نرسد و در شروع نیز به صورت suspenfd می باشد تا رخدادی اجازه اجرا به آن بدهد):



void YourFunction()
{
// Create the CEvent object that will be passed to the thread routine
CEvent* pEvent = new CEvent( FALSE, FALSE );

// Create a thread that will wait on the event
CWinThread* pThread;
pThread = ::AfxBeginThread( ThreadProc, pEvent, 0, 0, CREATE_SUSPENDED, NULL);
pThread->m_bAutoDelete = FALSE;
pThread->ResumeThread();

// Signal the thread to do the next work item
pEvent->SetEvent();

// Wait for the thread to consume the event and return
::WaitForSingleObject( pThread->m_hThread, INFINITE );
delete pThread;
}

UINT __cdecl ThreadProc( LPVOID lpParameter )
{
CEvent* pEvent = (CEvent*)( lpParameter );
VERIFY( pEvent != NULL );

// Wait for the event to be signaled
::WaitForSingleObject( pEvent->m_hObject, INFINITE );

// Terminate the thread
::AfxEndThread( 0, FALSE );
return 0L;
}

یا مثلا در حلقه بی نهایت می تواند از lock استفاده کرد تا در صورت رخدادی از حلقه خارج شود:



while( MultiLock.Lock( INFINITE, FALSE ) == WAIT_OBJECT_0 )
{
// ِDo something

// just an example:
//Notify main thread calculation is complete
pThis->m_pCalcFinished->SetEvent();
}

// Terminate the thread
::AfxEndThread( 0, FALSE );

و یا به صورت ساده با یک متغیر (قابل استفاده برای نمونه ها نیست):



while (var_ExitThread == false)
{
// Do something
}
// Terminate the thread
::AfxEndThread( 0, FALSE );


در هر حال بحث همزمان سازی ها بسیار وسیع و پیچیده می باشد و نیازمند مطالعه بیشتری می باشد.

Moharram
چهارشنبه 04 اردیبهشت 1387, 17:48 عصر
این روش سومی رو امتحان کردم و ظاهرا جواب گرفتم

با تشکر فراوان از Nima_NF