Oto kilka prostych sposobów, które mogą sprawić, że naprawisz problem ze strumieniem Win32 msdn.
Zatwierdzono: Fortect
- 7 minut na przeczytanie.
Funkcja tworzy nową lokalizację dla sposobu, w jaki proces. Twórca strumienia ma tylko osobiste wymagania dotyczące podania początkowego adresu prefiksu, którego zwykle powinien używać nowy strumień. Zazwyczaj właściwość startowa polega na utworzeniu funkcji zdefiniowanej w kodzie modelu (patrz ThreadProc , aby uzyskać dobre informacje). Ta funkcja jest prosta i nawet parametrowi przypisywana jest wartość DWORD. Proces a może tworzyć wiele wątków, które jednocześnie zarządzają tą samą funkcją.
Poniżej znajduje się prosty przykład pokazujący, jak wymyślić nowy wątek, który z kolei wykonuje lokalnie zdefiniowaną MyThreadFunction
danej osoby.
Wątek brzęczyka używa funkcji WaitForMultipleObjects do kontynuowania wszystkiego, aż wątki robocze zostaną usunięte. Wątek wywołujący zawiesza się, podczas gdy zasadniczo oczekuje; Aby kontynuować przetwarzanie, wątek wywołujący zwykle tworzy WaitForSingleObject i czeka na każdy znacznik z wątku roboczego do jego tematu Wait. Zauważ, że eksperci twierdzą, że jeśli zamkniesz uchwyt przepływu pracy przed zamknięciem witryny o zasięgu ogólnoświatowym, nie zakończy to przepływu użytkownika. Jednak uchwyt nie jest dostępny do użycia w przypadku kolejnych wywołań funkcji.
#include #włącz #include #define MAX_THREADS 3#define BUF_SIZE WINAPI 255dword MyThreadFunction (LPVOID lpParam);void ErrorHandler (LPTSTR lpszFunction);// Przykład niestandardowej struktury danych dla zwykle używanych strumieni.// To jest przekazywane z pustego wskaźnika, niewiarygodne, mogą to być dowolne dane podobne do pomysłu// można przekazać w jednym wskaźniku zerowym (LPVOID).typedef struct MyData int wart1; int wart2; MOJEDANE, (puste) PMEINEDATA;int_tmain () PMYDATA pDataArray [MAX_THREADS]; DWORD dwThreadIdArray [MAX_THREADS]; OBSŁUGA hThreadArray [MAX_THREADS]; // Utwórz MAX_THREADS wątki robocze. jak dla (int i = 0; i wart1 równa się i; pDataArray [i] -> wart2 równa się i + 100; // Utwórz wszystkie wątki, aby rozpocząć wykonywanie procesu. hThreadArray [i] = UtwórzWątek ( NULL, // Wycofaj atrybuty bezpieczeństwa 0, // użyj standardowego stosu dla każdego rozmiaru bitów MyThreadFunction, // dokładnie dokładna nazwa funkcji pDataArray [i], // argument roli wątku 0, // użyj domyślnych flag startowych & dwThreadIdArray [i]); // zapłać identyfikator wątku // Zwykle sprawdzamy zwróconą wartość z powodzeniem. // CreateThread, niezależnie od tego, czy się nie powiedzie, kończy działanie. // Dzięki temu pamięć mojego wątku zostanie automatycznie wyczyszczona. w przypadku (hThreadArray [i] == NULL) ErrorHandler (TEKST ("Utwórz wątek")); Wyjdź z procesu (3); // zakończenie cyklu tworzenia znanego wątku. // Poczekaj na zakończenie wszystkich ciągów. WaitForMultipleObjects (MAX_THREADS, hThreadArray, TRUE, INFINITE); // Zamknij mnóstwo wątków i przetwórz Alokację wolnej pamięci. in (int i = 0; i wart1, pDataArray-> wart2); StringCchLength (msgBuf, BUF_SIZE i cchStringSize); WriteConsole (hStdout, msgBuf, (DWORD) cchStringSize & dwChars, NULL); Zwraca 0; void ErrorHandler (LPTSTR lpszFunction) FORMAT_MESSAGE_IGNORE_INSERTS, ZERO, dw, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) i lpMsgBuf, 0, NULL); // Wyświetl komunikaty o błędzie. lpDisplayBuf = (LPVOID) LocalAlloc (LMEM_ZEROINIT, (lstrlen ((LPCTSTR) lpMsgBuf) + lstrlen ((LPCTSTR) lpszFunction) + 40) (puste) specyfikacje (TCHAR)); StringCchPrintf ((LPTSTR) lpDisplayBuf, LocalSize (lpDisplayBuf) / sizeof (TCHAR), TEKST („% s prawdopodobnie nie może trafić% d:% s”), lpszFunkcja, dw, lpMsgBuf); MessageBox (NULL, (LPCTSTR) lpDisplayBuf, TEXT ("Błąd"), MB_OK); // Swobodne przydzielanie tych buforów obsługi błędów. LokalnyBezpłatny (lpMsgBuf); LokalnyBezpłatny (lpDisplayBuf);
Funkcja MyThreadFunction
unika używania odtwarzania C (CRT), ponieważ wiele jej funkcji jest prawdopodobnie, ale nie wątkowo bezpiecznych, zwłaszcza jeśli nie używasz wielowątkowego CRT. Jeśli chcesz nosić w crt idealną funkcję ThreadProc
, użyj zamiast tego funkcji _beginthreadex .
Zatwierdzono: Fortect
Fortect to najpopularniejsze i najskuteczniejsze narzędzie do naprawy komputerów na świecie. Miliony ludzi ufają, że ich systemy działają szybko, płynnie i bez błędów. Dzięki prostemu interfejsowi użytkownika i potężnemu silnikowi skanowania, Fortect szybko znajduje i naprawia szeroki zakres problemów z systemem Windows - od niestabilności systemu i problemów z bezpieczeństwem po zarządzanie pamięcią i wąskie gardła wydajności.
Generalnie ryzykowne jest przekazywanie domu absolutnej zmiennej lokalnej, jeśli wątek produkcyjny kończy pracę przed nowym wątkiem, ponieważ wszystkie podpowiedzi stają się nieważne. Zamiast tego przekaż dynamicznie nadawane powiadomienie o pamięci lub pozwól, aby bieżące miejsce rozwoju poczekało na zakończenie nowego wiązania. Dane mogą być również przekazywane z bloku tworzenia do strumienia zastępczego za pomocą zmiennych globalnych. Jako całość zwykle jest to konieczne, aby zsynchronizować połączenie między wieloma wątkami. Aby uzyskać dodatkowe informacje na temat synchronizacji, zobacz Wykonywanie synchronizacji wielowątkowej .
Twórca wątku może również użyć argumentów CreateThread do określenia:
- Opcje bezpieczeństwa zarządzania nową lokalizacją. Te atrybuty zabezpieczeń obejmują wielkość dziedziczenia identyfikacji osobistej, która określa, czy dojście może faktycznie sterować z dziedziczonych procesów podrzędnych. Funkcje bezpieczeństwa zdecydowanie zawierają deskryptor bezpieczeństwa, którego system używałby do sprawdzania dostępu do wszystkich kolejnych marek zablokowanych wątków przed przyznaniem dostępu.
- Początkowy stos, który odnosi się do wartości nowego wątku. Sumowanie tematów jest automatycznie alokowane w przestrzeni procesu cram; System niewątpliwie powiększy stos, chociaż będzie potrzebny, i zwolni go za każdym razem, gdy ostrożny wątek się zakończy. Aby uzyskać więcej informacji, zobacz Rozmiar stosu wątków .
Przyspiesz teraz wydajność swojego komputera dzięki temu prostemu pobieraniu.
Wątek twórcy musi podać dowolny adres rejestracyjny kodu, aby rozpocząć sznurek dla początkujących. Zwykle adres początkowy jest nazwą elementu, zdefiniowaną w kodzie (zobacz ThreadProc, aby uzyskać więcej informacji). Ta funkcja pobiera każdy parametr i zwraca wartość DWORD.
_Beginthread, ale także _Funkcje beginthreadex System przydziela sezon procesora do każdego pojedynczego wątku, dzięki czemu wszystkie posty mogą działać jednocześnie w absolutnym procesie. _beginthread, a co za tym idzie _beginthreadex, są podobne do funkcji CreateThread API Win32, ale mają następujące urządzenia: Inicjują pewne problemy z biblioteką odtwarzania C.
Wywołanie WaitForSingleObject() czeka na trafienie obiektu, aby zasygnalizować jego dostępność. Innymi słowy, określona procedura zapewnia lepszą obsługę wątku, nie wspominając o czekaniu na zakończenie tego wątku. Wątki zaplanowane za pomocą funkcji main() przestaną działać po zazwyczaj zakończeniu głównego wątku.