типове нишки: 1.UI – с цикли за съобщения; прозорци; пр: обмен файлове.
2. работни – фаонови задачи; пр. анимация на изображения.
създаване работна нишка с MFC: вместо ::CreateThread() - CWinThread::AfxBeginThread() [инициялизира среда на изпълнение, проверява състоянието й, обезопасява достъпа до run-time ф-ии].
CWinThread* pThread = AfxBeginThread( ThreadFunction, &threadinfo);
/* CWinThread* AfxBeginThread (AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTS lpSecurityAttrs = NULL) */ създаване UI нишка с MFC: има свой клас производе на CWinThread (подобен на клас на прил.):
class CUIThread : public CWinThread m_pMainWndShowWindow(..);
{ DECLARE_DYNCREATE (CUIThread) m_pMainWndUpdateWindow();
public: virtual BOOL InitInstance(); }; return TRUE; }
IMPLEMENT_DYNCREATE (CUIThread, CWinThread) class CMainWindow:
BOOL CUIThread::IniInstance() public CFrameWindow
{ m_pMainWnd = new CMainWindow; { // констр. - пуска нишката
// методи за обр. съобщения…
преустановяване на нишка с MFC: CWinThread::SuspendThread(); CWinThread:: ResumeThread(); брояч на прустановяването (0 – стартитване ).
приспиване на нишка с MFC: ::Sleep(време ); Sleep( 0 );
пр: анимации на множество обекти; анимации през различни интервали (Sleep( 0)).
завършване на нишка с MFC: 1. return;
2. AfxEndThread(); ::PostQuitMessage();
тест на състояние: DWORD test; ::GetExitCodeThread(pThreadm_hThread, &test);
изтриване обект от клас CWinThread: 1. MFC авт. изтрива указател към обекта при завършване на нишката.Дестукторът на CWinThread затваря и манипулатора й. Проблем възникава с … за привършила нишка. Ако копираме pThreadm_hThread в променлива в нишката преди завършването й – отново възможен проблем. Тогава:
-
CWinThread* pThread = AfxBeginThread (ThreadFunc, NULL, Thread_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
pTheadm_bAutoDelete = FALSE; pThreadResumeThread();
…..
::GetExitCodeThread(……); if(dwexitcode == STILL_ACTIVE) { ….}
else { /* нишката е преустановена */ delete pThread; }
завършване на друга нишка с MFC:
1.//нишка А 2.// нека нишка А се блокирва докато Б
flagContinue = 1; // се изпълнява.
CWinThread* pThread = AfxBeginThread ( HANDLE hThread =pThread
ThreadFunc, flagContinue); m_hThread; flagContunue = 0;
… flagContinue = 0; //нишка Б да завърши WaitForSingleObject(hThread,INFINITE);
//нишка Б //нишка Б
UINT ThreadFunc(LPVOID pParam)
{ int* flagContinue = (int*) pParam;
while(*flagContinue) {// работй }..
може да бъде: манипулатор на нишка, процес,обект за синхронизиране, нотификация за промяна на файл.
нива на приоритети на процеси:
IDLE_PRIORITY_CLASS; NORMAL_PRORITY_CLASS
HIGH_PRIORITY_CLASS REALTIME_PRIORITY_CLASS
относителни нива на приоритети на нишки:
THREAD_PRIORITY_IDLE (1,16) THREAD_PRIORITY_LOWEST
TREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_ABOVE_NORMAL
THREAD_PRIORITY_NORMAL THREAD_PIORTY_HIGHEST
THREAD_PRIORITY_TIME_CRITICAL (15,31)
1.всяка нишка използва само обектите, които самата тя е създала, а не такива от други, които да и се подават.
2.ако все пак се налага, то прозорци, GDI обекти и др. се подават с манипулатори, а не с указатели.
-
потребителския интерфейс се съсредоточва в главната нишка, обновявания от другите нишки се основават на изпращане съобщения към главната.
-
локални за нишка данни и структури с епоместват в собствения й стек и изчезват заедно с преустановяването й ( което е недефинирано във времето) – следователно стават недостъпни за останалите нишки. Добре е ако са нужни да се създават в тях и предават като параметър при създаване на съответната нишка.
-
когато завърши първичната нишка на прил. (процес) завършват и останалите нишки в процеса.
-
MFC класовете са нишково обезопасени на ниво клас , но не на ниво обект. Следователно 2 нишки могат да работят едновременно с обекти от 1 клас, но не е безопасно да работят с една инстанция на класа едновременно.
Синхронизиране на нишки с MFC
критични секции: CCriticalSection::Lock() CCriticalSection::Unlock()
Win32 API ф-ии за атомарни действия: за нарастване стойност, намаляване, размяна, сравнение и размяна, размяна и събиране….
взаимни изключвания (mutex):
разлики с кр. секции: 1. работи в процес или м/ду процеси;
-
ако нишка заключи кр. секция и завърши, тя блокирва останалите. Системата отключва изоставени от привършили mutex блокове и отблок. никите, които чакат.
събития: CEvent::SetEvent() CEvent::ResetEvent() CEvent::PulseEvent() //устан. и чисти
CEvent::Lock() //блокира нишка пред събитие.
едно събитие може да се чака от множество нишки. Има автоматично (авт. става несигнализирано след отблокирване първата нишка, която го чака) изчистваеми и ръчно изчистваеми събития.
-
Ако искаме само 1 нишка да се отблокира – автоматично..
-
ако искаме повече нишки да се отблокират –събитие с ръчно изчистване и PulseEvent() (установява и изчиства, но гарантира пускане на всички нишки.
семафори: синхронизира в рамки на процес и м/ду процеси
CSemaphore(начален брояч на ресуси, максимален брояч на ресурса, [име – ако ще го предаваме м/ду процеси], [ атрибути за сигурност]);
g_semaphore.Lock() g_semaphore.Unlock()
Сподели с приятели: |