1 / 21

Programowanie wielowątkowe

Jarosław Kuchta. Programowanie wielowątkowe. Procesy i wątki w systemie Windows. Windows jest systemem wielowątkowym. Każdy proces ma przynajmniej jeden wątek, chociaż może mieć wiele wątków. Start programu, to start głównego wątku procesu. Główny wątek może uruchomić inny, poboczny wątek.

Download Presentation

Programowanie wielowątkowe

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Jarosław Kuchta Programowanie wielowątkowe

  2. Procesy i wątki w systemie Windows • Windows jest systemem wielowątkowym. • Każdy proces ma przynajmniej jeden wątek, chociaż może mieć wiele wątków. • Start programu, to start głównego wątku procesu. • Główny wątek może uruchomić inny, poboczny wątek. • Zamknięcie programu, to zamknięcie wszystkich wątków procesu.

  3. Programowanie wielowątkowe w języku C • Start programu: • main(), wmain() – w programie konsoli • WinMain(), wWinMain() – w programie okienkowym • Procedura osobnego wątku: void ThreadProc(void *param) { … _endthread(); // zakończenie wątku }

  4. Funkcje sterujące wątkami zadeklarowane w process.h: • _beginthread – rozpoczęcie wątku • _beginthreadex – rozszerzone rozpoczęcie wątku • _endthread – zakończenie wątku • _endthreadex – rozszerzone zakończenie wątku

  5. Przykład – funkcja wątku void ThreadProc(void *param) { // ten wątek po prostu wypisuje parametr int h=*((int*)param); printf("%d Thread is Running!\n",h); _endthread(); }

  6. Przykład – funkcja główna int main() { int n; int i; int val = 0; HANDLE handle; printf("\t Thread Demo\n"); printf("Enter the number of threads : "); scanf("%d",&n); for(i=1;i<=n;i++) { val = i; handle = (HANDLE) _beginthread( ThreadProc,0,&val); // utworzeniewątku WaitForSingleObject(handle,INFINITE); // oczekiwanie na zakończenie wątku } return 0; }

  7. Programowanie wielowątkowe w MFC • Hierarchia klas MFC: • CObject – obiekt abstrakcyjny • CCmdTarget – obiekt aktywny • CWinThread – wątek Windows • CWinApp – aplikacja Windows • Aplikacja Windows jest wątkiem! • Dwa rodzaje wątków: • User Interface – wątek oparty o okna • Worker – wątek pracujący w tle

  8. Użyteczne dane • m_nThreadID – identyfikator bieżącego wątku • m_hThread – uchwyt bieżącego wątku • m_bAutoDelete – czy wątek ma się sam usunąć po zamknięciu?

  9. Funkcje wątkowe • Funkcje globalne: • AfxBeginThread – utworzenie wątku • AfxEndThread – zamknięcie wątku • Metody obiektowe: • CreateThread – utworzenie i wystartowanie wątku • SuspendThread – zawieszenie wątku (inkrementacja licznika zawieszeń) • ResumeThread – wznowienie wątku (dekrementacja licznika zawieszeń) • SetThreadPriority – ustawienie priorytetu wątku • GetThreadPriority – pobranie priorytetu wątku

  10. Priorytety wątków • THREAD_PRIORITY_HIGHEST • THREAD_PRIORITY_ABOVE_NORMAL • THREAD_PRIORITY_NORMAL • THREAD_PRIORITY_BELOW_NORMAL • THREAD_PRIORITY_IDLE

  11. Przykład z użyciem funkcji Afx CwinThread *pThread = AfxBeginThread( ThreadFunction, &data); UINT ThreadFunction(LPVOID param) { DWORD result =0 ; // do somthig AfxEndThread(exitCode); return result; }

  12. Kończenie wątku • funkcja TerminateThread() • funkcja ExitThread() • instrukcja return – zalecana, pozostałe nie czyszczą stosu.

  13. Programowanie wielowątkowe w C# (1) // współdzielona zmienna private string _threadOutput = ""; // funkcja pierwszego wątku void DisplayThread1() {while (_stopThreads == false){ Console.WriteLine("Display Thread 1"); _threadOutput = "Hello Thread1"; Thread.Sleep(1000); // symulacja działania pierwszego wątku Console.WriteLine("Thread 1 Output --> {0}", _threadOutput); } }

  14. Programowanie wielowątkowe w C# (2) // funkcja drugiego wątku void DisplayThread2() {while (_stopThreads == false){ Console.WriteLine("Display Thread 2"); _threadOutput = "Hello Thread2"; Thread.Sleep(1000); // symulacja działania drugiego wątku Console.WriteLine("Thread 2 Output --> {0}", _threadOutput); } }

  15. Programowanie wielowątkowe w C# - inicjacja wątków Class1() { // utworzenie dwóch wątków Thread thread1 = new Thread(new ThreadStart(DisplayThread1)); Thread thread2 = new Thread(new ThreadStart(DisplayThread2)); // wystartowanie wątków thread1.Start(); thread2.Start(); }

  16. Wynik Współdzielona zmienna jest asynchronicznie nadpisywana

  17. Synchronizacja przez lock (1) // współdzielona zmienna private string _threadOutput = ""; // funkcja pierwszego wątku void DisplayThread1() { while (_stopThreads == false) { lock (this) // blokada na własnej instancji { Console.WriteLine("Display Thread 1"); _threadOutput = "Hello Thread1"; Thread.Sleep(1000); // symulacja działania pierwszego wątku Console.WriteLine("Thread 1 Output --> {0}", _threadOutput); } } }

  18. Synchronizacja przez lock (2) // funkcja drugiego wątku void DisplayThread2() {while (_stopThreads == false){ lock(this) // blokada na własnej instancji { Console.WriteLine("Display Thread 2"); _threadOutput = "Hello Thread2"; Thread.Sleep(1000); // symulacja działania drugiego wątku Console.WriteLine("Thread 2 Output --> {0}", _threadOutput); } } }

  19. Wynik (po synchronizacji)

  20. Synchronizacja przez AutoResetEvent (1) // zmienne sygnałowe do wzajemnego odblokowywania AutoResetEvent _blockThread1 = new AutoResetEvent(false); AutoResetEvent _blockThread2 = new AutoResetEvent(true); void DisplayThread_1() {while (_stopThreads == false){ // pierwszy wątek czeka, gdy drugi działa _blockThread1.WaitOne(); // po wołaniu Set przez drugi wątek, pierwszy kontynuuje działanie Console.WriteLine("Display Thread 1"); _threadOutput = "Hello Thread 1"; Thread.Sleep(1000); // symulacja działania pierwszego wątku Console.WriteLine("Thread 1 Output --> {0}", _threadOutput); // zakończenie działania – odblokowanie drugiego wątku _blockThread2.Set(); } }

  21. Synchronizacja przez AutoResetEvent (2) void DisplayThread_2() { while (_stopThreads == false){ // drugi wątek czeka, gdy pierwszy działa _blockThread2.WaitOne();  // po wołaniu Set przez pierwszy wątek, drugi kontynuuje działanie Console.WriteLine("Display Thread 2"); _threadOutput = "Hello Thread 2"; Thread.Sleep(1000); // symulacja działania drugiego wątku Console.WriteLine("Thread 2 Output --> {0}", _threadOutput);  // zakończenie działania – odblokowanie pierwszego wątku _blockThread1.Set(); } }

More Related