Aplikacja wielowątkowa strasznie obciąża procka.

0

Witam,
od wczoraj czytam na temat programowania wielowątkowego w WinAPI tylko, że moja pierwsza próba strasznie obciąża procka, nawet do 100% (mam w miarę przyzwoity dwurdzeniowy procesor), przedstawiam kod i bardzo proszę o rady:

DWORD WINAPI FunkcjaWatku(PVOID pvParam){
	
		HWND hwnd;
		hwnd=(HWND)pvParam;
	           for(int i=0;i<44;i++){
		   Rury rury3(&hwnd, stary, RGB(12,i+100,i-i*3), 1100, 510+((*dPos)*2), 1200, 460+((*dPos)*2),8);  
                   //tutaj wywluje funkcje rysujaca kreski, konstruktor klasy
 
				if(i==21) i=0;}
	              return 0;
}	

a wątek tworzę w WM_PAINT:
CreateThread(NULL, 0, FunkcjaWatku, (PVOID)hwnd, 0, &IdWatku);

Prezentuje też cały kod

#include "centrum.h"

	HWND okno1, scroll1, button, *button1;
	HINSTANCE *hInst;
	int  uPos=0, *dPos;
	RECT rcOkno;
	Okno skrol;
	bool przyc=false;
	POINT stary; 
	POINT kursor;
	const WORD ID_TIMER = 1;
	int *a,b=255,c=255, d=0, e=0,f=0;
	DWORD IdWatku;
	COLORREF color, color1;
	
	
DWORD WINAPI FunkcjaWatku(PVOID pvParam){
	
		HWND hwnd;
		hwnd=(HWND)pvParam;
	for(int i=0;i<44;i++){
		Rury rury3(&hwnd, stary, RGB(12,i+100,i-i*3), 1100, 510+((*dPos)*2), 1200, 460+((*dPos)*2),8);

				if(i==21) i=0;}
	return 0;
}	



LRESULT CALLBACK WndProc1(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK WndProc2(HWND,UINT,WPARAM,LPARAM);

//---------------------------------------------------------------------------------------------------------	
INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lStart,INT nShow)
{	
	MSG msg;
	hInst=&hInstance;
	
		Okno glowne(&hInstance, WndProc1, &okno1);						
				
		while(GetMessage(&msg, NULL, 0, 0)) 
			{ 
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
				}

	return 0;
}

//---------------------------------------------------------------------------------------------------------	
LRESULT CALLBACK WndProc1(HWND hwnd,UINT msg,WPARAM wPar,LPARAM lPar)
{	HINSTANCE hProg = GetModuleHandle(NULL);
	dPos = &uPos;	
SetTimer(hwnd, ID_TIMER, 50, NULL);
if(SetTimer(hwnd, ID_TIMER, 50, NULL) == 0)
 MessageBox(hwnd, "Nie można utworzyć timera!", "Kurde", MB_ICONSTOP);


	switch(msg)
  {
		case WM_CREATE:
			{	
				button=CreateWindowEx(0,WC_BUTTON,"dupa",WS_CHILD | WS_VISIBLE,1050,50,200,70,hwnd,0,hProg,0);
				scroll1=CreateWindowEx(0,"SCROLLBAR",NULL,WS_CHILD | WS_VISIBLE | SBS_VERT, 987,338,30,34,hwnd,0,hProg,0);
				SetScrollRange(scroll1,SB_CTL,0,540,true);

					break;
			}
//---------------------------------------------------------------------------------------------
		case WM_VSCROLL:
			{
				skrol.scrol(&wPar,&lPar,&scroll1,&hwnd,dPos);
				
				break;
			}
//---------------------------------------------------------------------------------------------
		case WM_TIMER:
			{	
				f++;			
				Rury rury(&hwnd, stary, RGB(0,b,d), 750, 440+((*dPos)*2),730, 510+((*dPos)*2),2);
				Rury rury1(&hwnd, stary, RGB(0,c,e), 770, 450+((*dPos)*2), 730, 510+((*dPos)*2),2);
				Rury rury2(&hwnd, stary, RGB(0,c,e), 790, 460+((*dPos)*2), 730, 510+((*dPos)*2),2);
				Rury rury3(&hwnd, stary, RGB(0,c,e), 730, 510+((*dPos)*2), 400, 460+((*dPos)*2),4);
				if(f%2==1){ b=0; d=255; e=255; c=0;}
				if(f==3) {f=0; d=0; b=255; c=255; e=0;}

		break;
			}
//---------------------------------------------------------------------------------------------
		case WM_ERASEBKGND:
			{

			break;
			}
//---------------------------------------------------------------------------------------------
		case WM_COMMAND:
			{			
				
		break;
			}
//---------------------------------------------------------------------------------------------
		case WM_PAINT:
			{	GetClientRect(hwnd, &rcOkno);			
				PAINTSTRUCT ps;
				BITMAP info1, info2;
				HDC hdc1 = BeginPaint(hwnd, &ps);
				
				HDC hdcbufor = CreateCompatibleDC(hdc1);
				HDC hdcnowy1 = CreateCompatibleDC(hdc1);
				
					HBITMAP bmp1 = (HBITMAP)LoadImage(NULL, "C:\\Users\\Ziggy Mayla\\Desktop\\wwa.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
						if(bmp1==0){
							MessageBox(0,"Nie można","Brak pliku",MB_ICONERROR); 
								return 0;}

						GetObject(bmp1, sizeof(info1),&info1);
						SelectObject(hdcnowy1,bmp1);

						HBITMAP bmpBuf = CreateCompatibleBitmap(hdc1, info1.bmWidth, info1.bmHeight);
						HBITMAP bmpBufO = (HBITMAP)SelectObject(hdcbufor, bmpBuf);

							BitBlt(hdcbufor,0,*dPos, info1.bmWidth, info1.bmHeight, hdcnowy1, 0,0,SRCCOPY);							
							BitBlt(hdc1, 0, *dPos, info1.bmWidth, info1.bmHeight, hdcbufor, 0, 0, SRCCOPY);			
						
						DeleteObject(bmpBuf);
						DeleteObject(bmpBufO);
						DeleteObject(hdcnowy1);
						DeleteObject(bmp1);

				
				HDC hdcnowy2 = CreateCompatibleDC(hdc1);					
					HBITMAP bmp2 = (HBITMAP)LoadImage(NULL, "C:\\Users\\Ziggy Mayla\\Desktop\\filtr.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
						
								
					
					
					if(bmp2==0){ MessageBox(0,"Nie można","Brak pliku",MB_ICONERROR); return 0;}
							GetObject(bmp2, sizeof(info2), &info2);
							SelectObject(hdcnowy2,bmp2);

					//TransparentBlt(hdc1,700, 480+((*dPos)*2), info2.bmWidth, info2.bmHeight,hdcnowy2,0, 0,info2.bmWidth, info2.bmHeight,RGB(0,0,0));
					BitBlt(hdc1, 700, 480+((*dPos)*2), info2.bmWidth, info2.bmHeight, hdcnowy2, 0, 0, SRCCOPY);
				DeleteObject(bmp2);
				DeleteObject(hdcnowy2);
				
				CreateThread(NULL, 0, FunkcjaWatku, (PVOID)hwnd, 0, &IdWatku);
				

				EndPaint(hwnd, &ps);
				
				
				break;
			}
//---------------------------------------------------------------------------------------------------------	
		case WM_LBUTTONDOWN:
		{
			//przyc=true;
			//SendMessage(hwnd, WM_MOUSEMOVE, wPar, lPar);
		}
		break;
		case WM_LBUTTONUP:
		{
			
		}
		break;
		case WM_MOUSEMOVE:
		{	
			//GetCursorPos(&kursor);
		//	if( (int)kursor.x < 760 && (int)kursor.x > 700 && (int)kursor.y < 550 && (int)kursor.y > 500 ) MessageBox(hwnd," "," ",MB_OK);


		}
		break;
//---------------------------------------------------------------------------------------------------------	
		case WM_CLOSE:
			{	KillTimer(hwnd,ID_TIMER);
				DestroyWindow(hwnd);
				PostQuitMessage(0);
					break;
			}
	

		default:
				return DefWindowProc(hwnd,msg,wPar,lPar);

	  
	}
	return 0;
}
//---------------------------------------------------------------------------------------------------------	
LRESULT CALLBACK WndProc2(HWND hwnd,UINT msg,WPARAM,LPARAM)
{
	switch(msg)
	 {
	 case WM_KEYDOWN:
		{
	   Beep(0, 0);
		}
	 break;

	 }
	 return 0;
	
};


0

nie wnikając w kod tylko w pierwsze zdanie, WM_PAINT jest fireowany baaaaaardzo często, i za każdym razem tworzysz nowy wątek, więc nic dziwnego że zamula. Wątek robi się po coś a nie byle by tylko zrobić :)

0

Ok, dzięki teraz przynajmniej aplikacja sama nie zamula, tylko dalej mam procka na ~80%, można jeszcze coś z tym zrobić?

0
warszyk napisał(a)

Ok, dzięki teraz przynajmniej aplikacja sama nie zamula, tylko dalej mam procka na ~80%, można jeszcze coś z tym zrobić?

wywal z WM_PAINTA to:

HBITMAP bmp1 = (HBITMAP)LoadImage(NULL, "C:\\Users\\Ziggy Mayla\\Desktop\\wwa.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

wywołaj to raz na początku aplikacji - co odrysowanie odwołujesz się do HDD- co prawda windows cache-uje ten plik, ale dostęp do niego nie jest darmowy w czasie.

CreateThread(NULL, 0, FunkcjaWatku, (PVOID)hwnd, 0, &IdWatku);

tu już ktoś Ci podpowiedział dobrze - tworzenie wątku jest kosztowne, jeśli potrzebujesz kilku wątków, stwórz sobie pule wątków uśpionych(CREATE_SUSPENDED) gdzieś na dzień dobry i odpalaj je w miarę potrzeby poprzez ResumeThread();

kolejna rzecz - w XP i Viście na czas rysowania po powierzchni okna GDI zakłada sekcję krytyczną - wiec kolejne wywołania GDI odnoszące się do tego samego DC czekają na jego zwolnienie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1